public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/22] Direct decode in emulator
@ 2010-07-29 12:11 Avi Kivity
  2010-07-29 12:11 ` [PATCH 01/22] KVM: x86 emulator: drop parentheses in repreat macros Avi Kivity
                   ` (22 more replies)
  0 siblings, 23 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Currently the emulator decoder is indirect in two ways: groups are looked up
in a separate table based on group number; and opcode execution is looked up
in a big switch (actually two) after the opcode flags lookup.

This patchset converts groups to direct decode and begins the work for opcode
decode.

The motivations are:
- reduce errors from discrepancies between the two tables (like we had for
  IRET)
- make the code easier to read, removing many switch () statements
- eventually remove the #UD mini-decoder in x86.c by adding subgroup support
  to the emulator

Avi Kivity (22):
  KVM: x86 emulator: drop parentheses in repreat macros
  KVM: x86 emulator: introduce 'struct opcode'
  KVM: x86 emulator: Add wrappers for easily defining opcodes
  KVM: x86 emulator: move group tables to top
  KVM: x86 emulator: reserve group code 0
  KVM: x86 emulator: allow specifying group directly in opcode
  KVM: x86 emulator: convert group 1 to new style
  KVM: x86 emulator: convert group 1A to new style
  KVM: x86 emulator: convert group 3 to new style
  KVM: x86 emulator: convert group 4 to new style
  KVM: x86 emulator: convert group 5 to new style
  KVM: x86 emulator: convert group 7 to new style
  KVM: x86 emulator: convert group 8 to new style
  KVM: x86 emulator: convert group 9 to new style
  KVM: x86 emulator: drop support for old-style groups
  KVM: x86 emulator: move ByteOp and Dst back to bits 0:3
  KVM: x86 emulator: store x86_emulate_ops in emulation context
  KVM: x86 emulator: allow storing emulator execution function in
    decode tables
  KVM: x86 emulator: move x86_decode_insn() downwards
  KVM: x86 emulator: move decode tables downwards
  KVM: x86 emulator: allow repeat macro arguments to contain commas
  KVM: x86 emulator: convert some push instructions to direct decode

 arch/x86/include/asm/kvm_emulate.h |   10 +-
 arch/x86/kvm/emulate.c             | 1253 +++++++++++++++++++-----------------
 arch/x86/kvm/x86.c                 |    7 +-
 3 files changed, 661 insertions(+), 609 deletions(-)


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 01/22] KVM: x86 emulator: drop parentheses in repreat macros
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 02/22] KVM: x86 emulator: introduce 'struct opcode' Avi Kivity
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

The parenthese make is impossible to use the macros with initializers that
require braces.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 3d88151..2f1b2c2 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -95,10 +95,10 @@
 #define Src2One     (3<<29)
 #define Src2Mask    (7<<29)
 
-#define X2(x) (x), (x)
-#define X3(x) X2(x), (x)
+#define X2(x) x, x
+#define X3(x) X2(x), x
 #define X4(x) X2(x), X2(x)
-#define X5(x) X4(x), (x)
+#define X5(x) X4(x), x
 #define X6(x) X4(x), X2(x)
 #define X7(x) X4(x), X3(x)
 #define X8(x) X4(x), X4(x)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/22] KVM: x86 emulator: introduce 'struct opcode'
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
  2010-07-29 12:11 ` [PATCH 01/22] KVM: x86 emulator: drop parentheses in repreat macros Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 03/22] KVM: x86 emulator: Add wrappers for easily defining opcodes Avi Kivity
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

This will hold all the information known about the opcode.  Currently, this
is just the decode flags.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   20 ++++++++++++--------
 1 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 2f1b2c2..afe778a 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -108,7 +108,11 @@ enum {
 	Group1, Group1A, Group3, Group4, Group5, Group7, Group8, Group9,
 };
 
-static u32 opcode_table[256] = {
+struct opcode {
+	u32 flags;
+};
+
+static struct opcode opcode_table[256] = {
 	/* 0x00 - 0x07 */
 	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
 	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
@@ -222,7 +226,7 @@ static u32 opcode_table[256] = {
 	ImplicitOps, ImplicitOps, Group | Group4, Group | Group5,
 };
 
-static u32 twobyte_table[256] = {
+static struct opcode twobyte_table[256] = {
 	/* 0x00 - 0x0F */
 	0, Group | GroupDual | Group7, 0, 0,
 	0, ImplicitOps, ImplicitOps | Priv, 0,
@@ -284,7 +288,7 @@ static u32 twobyte_table[256] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
-static u32 group_table[] = {
+static struct opcode group_table[] = {
 	[Group1*8] =
 	X7(Lock), 0,
 	[Group1A*8] =
@@ -313,7 +317,7 @@ static u32 group_table[] = {
 	0, DstMem64 | ModRM | Lock, 0, 0, 0, 0, 0, 0,
 };
 
-static u32 group2_table[] = {
+static struct opcode group2_table[] = {
 	[Group7*8] =
 	SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM | Priv,
 	SrcNone | ModRM | DstMem | Mov, 0,
@@ -1005,13 +1009,13 @@ done_prefixes:
 			c->op_bytes = 8;	/* REX.W */
 
 	/* Opcode byte(s). */
-	c->d = opcode_table[c->b];
+	c->d = opcode_table[c->b].flags;
 	if (c->d == 0) {
 		/* Two-byte opcode? */
 		if (c->b == 0x0f) {
 			c->twobyte = 1;
 			c->b = insn_fetch(u8, 1, c->eip);
-			c->d = twobyte_table[c->b];
+			c->d = twobyte_table[c->b].flags;
 		}
 	}
 
@@ -1024,9 +1028,9 @@ done_prefixes:
 		group = (group << 3) + ((c->modrm >> 3) & 7);
 		c->d &= ~(Group | GroupDual | GroupMask);
 		if (dual && (c->modrm >> 6) == 3)
-			c->d |= group2_table[group];
+			c->d |= group2_table[group].flags;
 		else
-			c->d |= group_table[group];
+			c->d |= group_table[group].flags;
 	}
 
 	/* Unrecognised? */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/22] KVM: x86 emulator: Add wrappers for easily defining opcodes
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
  2010-07-29 12:11 ` [PATCH 01/22] KVM: x86 emulator: drop parentheses in repreat macros Avi Kivity
  2010-07-29 12:11 ` [PATCH 02/22] KVM: x86 emulator: introduce 'struct opcode' Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 04/22] KVM: x86 emulator: move group tables to top Avi Kivity
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Once 'struct opcode' grows, its initializer will become more complicated.
Wrap the simple initializers in a D() macro, and replace the empty initializers
with an even simpler N macro.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |  294 ++++++++++++++++++++++++-----------------------
 1 files changed, 150 insertions(+), 144 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index afe778a..cd8a219 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -112,220 +112,226 @@ struct opcode {
 	u32 flags;
 };
 
+#define D(_y) { .flags = (_y) }
+#define N    D(0)
+
 static struct opcode opcode_table[256] = {
 	/* 0x00 - 0x07 */
-	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
-	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
 	/* 0x08 - 0x0F */
-	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
-	ImplicitOps | Stack | No64, 0,
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	D(ImplicitOps | Stack | No64), N,
 	/* 0x10 - 0x17 */
-	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
-	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
 	/* 0x18 - 0x1F */
-	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
-	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
 	/* 0x20 - 0x27 */
-	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
 	/* 0x28 - 0x2F */
-	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
 	/* 0x30 - 0x37 */
-	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
 	/* 0x38 - 0x3F */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
-	0, 0,
+	D(ByteOp | DstMem | SrcReg | ModRM), D(DstMem | SrcReg | ModRM),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	N, N,
 	/* 0x40 - 0x4F */
-	X16(DstReg),
+	X16(D(DstReg)),
 	/* 0x50 - 0x57 */
-	X8(SrcReg | Stack),
+	X8(D(SrcReg | Stack)),
 	/* 0x58 - 0x5F */
-	X8(DstReg | Stack),
+	X8(D(DstReg | Stack)),
 	/* 0x60 - 0x67 */
-	ImplicitOps | Stack | No64, ImplicitOps | Stack | No64,
-	0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
-	0, 0, 0, 0,
+	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+	N, D(DstReg | SrcMem32 | ModRM | Mov) /* movsxd (x86/64) */ ,
+	N, N, N, N,
 	/* 0x68 - 0x6F */
-	SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0,
-	DstDI | ByteOp | Mov | String, DstDI | Mov | String, /* insb, insw/insd */
-	SrcSI | ByteOp | ImplicitOps | String, SrcSI | ImplicitOps | String, /* outsb, outsw/outsd */
+	D(SrcImm | Mov | Stack), N, D(SrcImmByte | Mov | Stack), N,
+	D(DstDI | ByteOp | Mov | String), D(DstDI | Mov | String), /* insb, insw/insd */
+	D(SrcSI | ByteOp | ImplicitOps | String), D(SrcSI | ImplicitOps | String), /* outsb, outsw/outsd */
 	/* 0x70 - 0x7F */
-	X16(SrcImmByte),
+	X16(D(SrcImmByte)),
 	/* 0x80 - 0x87 */
-	ByteOp | DstMem | SrcImm | ModRM | Group | Group1,
-	DstMem | SrcImm | ModRM | Group | Group1,
-	ByteOp | DstMem | SrcImm | ModRM | No64 | Group | Group1,
-	DstMem | SrcImmByte | ModRM | Group | Group1,
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
+	D(ByteOp | DstMem | SrcImm | ModRM | Group | Group1),
+	D(DstMem | SrcImm | ModRM | Group | Group1),
+	D(ByteOp | DstMem | SrcImm | ModRM | No64 | Group | Group1),
+	D(DstMem | SrcImmByte | ModRM | Group | Group1),
+	D(ByteOp | DstMem | SrcReg | ModRM), D(DstMem | SrcReg | ModRM),
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
 	/* 0x88 - 0x8F */
-	ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov,
-	ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	DstMem | SrcNone | ModRM | Mov, ModRM | DstReg,
-	ImplicitOps | SrcMem16 | ModRM, Group | Group1A,
+	D(ByteOp | DstMem | SrcReg | ModRM | Mov), D(DstMem | SrcReg | ModRM | Mov),
+	D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem | ModRM | Mov),
+	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | DstReg),
+	D(ImplicitOps | SrcMem16 | ModRM), D(Group | Group1A),
 	/* 0x90 - 0x97 */
-	DstReg, DstReg, DstReg, DstReg,	DstReg, DstReg, DstReg, DstReg,
+	D(DstReg), D(DstReg), D(DstReg), D(DstReg),	D(DstReg), D(DstReg), D(DstReg), D(DstReg),
 	/* 0x98 - 0x9F */
-	0, 0, SrcImmFAddr | No64, 0,
-	ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
+	N, N, D(SrcImmFAddr | No64), N,
+	D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
 	/* 0xA0 - 0xA7 */
-	ByteOp | DstAcc | SrcMem | Mov | MemAbs, DstAcc | SrcMem | Mov | MemAbs,
-	ByteOp | DstMem | SrcAcc | Mov | MemAbs, DstMem | SrcAcc | Mov | MemAbs,
-	ByteOp | SrcSI | DstDI | Mov | String, SrcSI | DstDI | Mov | String,
-	ByteOp | SrcSI | DstDI | String, SrcSI | DstDI | String,
+	D(ByteOp | DstAcc | SrcMem | Mov | MemAbs), D(DstAcc | SrcMem | Mov | MemAbs),
+	D(ByteOp | DstMem | SrcAcc | Mov | MemAbs), D(DstMem | SrcAcc | Mov | MemAbs),
+	D(ByteOp | SrcSI | DstDI | Mov | String), D(SrcSI | DstDI | Mov | String),
+	D(ByteOp | SrcSI | DstDI | String), D(SrcSI | DstDI | String),
 	/* 0xA8 - 0xAF */
-	DstAcc | SrcImmByte | ByteOp, DstAcc | SrcImm, ByteOp | DstDI | Mov | String, DstDI | Mov | String,
-	ByteOp | SrcSI | DstAcc | Mov | String, SrcSI | DstAcc | Mov | String,
-	ByteOp | DstDI | String, DstDI | String,
+	D(DstAcc | SrcImmByte | ByteOp), D(DstAcc | SrcImm), D(ByteOp | DstDI | Mov | String), D(DstDI | Mov | String),
+	D(ByteOp | SrcSI | DstAcc | Mov | String), D(SrcSI | DstAcc | Mov | String),
+	D(ByteOp | DstDI | String), D(DstDI | String),
 	/* 0xB0 - 0xB7 */
-	X8(ByteOp | DstReg | SrcImm | Mov),
+	X8(D(ByteOp | DstReg | SrcImm | Mov)),
 	/* 0xB8 - 0xBF */
-	X8(DstReg | SrcImm | Mov),
+	X8(D(DstReg | SrcImm | Mov)),
 	/* 0xC0 - 0xC7 */
-	ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM,
-	0, ImplicitOps | Stack, 0, 0,
-	ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
+	D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM),
+	N, D(ImplicitOps | Stack), N, N,
+	D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov),
 	/* 0xC8 - 0xCF */
-	0, 0, 0, ImplicitOps | Stack,
-	ImplicitOps, SrcImmByte, ImplicitOps | No64, ImplicitOps,
+	N, N, N, D(ImplicitOps | Stack),
+	D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps),
 	/* 0xD0 - 0xD7 */
-	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
-	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
-	0, 0, 0, 0,
+	D(ByteOp | DstMem | SrcImplicit | ModRM), D(DstMem | SrcImplicit | ModRM),
+	D(ByteOp | DstMem | SrcImplicit | ModRM), D(DstMem | SrcImplicit | ModRM),
+	N, N, N, N,
 	/* 0xD8 - 0xDF */
-	0, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, N, N, N, N, N,
 	/* 0xE0 - 0xE7 */
-	0, 0, 0, 0,
-	ByteOp | SrcImmUByte | DstAcc, SrcImmUByte | DstAcc,
-	ByteOp | SrcImmUByte | DstAcc, SrcImmUByte | DstAcc,
+	N, N, N, N,
+	D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc),
+	D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc),
 	/* 0xE8 - 0xEF */
-	SrcImm | Stack, SrcImm | ImplicitOps,
-	SrcImmFAddr | No64, SrcImmByte | ImplicitOps,
-	SrcNone | ByteOp | DstAcc, SrcNone | DstAcc,
-	SrcNone | ByteOp | DstAcc, SrcNone | DstAcc,
+	D(SrcImm | Stack), D(SrcImm | ImplicitOps),
+	D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps),
+	D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc),
+	D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc),
 	/* 0xF0 - 0xF7 */
-	0, 0, 0, 0,
-	ImplicitOps | Priv, ImplicitOps, ByteOp | Group | Group3, Group | Group3,
+	N, N, N, N,
+	D(ImplicitOps | Priv), D(ImplicitOps), D(ByteOp | Group | Group3), D(Group | Group3),
 	/* 0xF8 - 0xFF */
-	ImplicitOps, 0, ImplicitOps, ImplicitOps,
-	ImplicitOps, ImplicitOps, Group | Group4, Group | Group5,
+	D(ImplicitOps), N, D(ImplicitOps), D(ImplicitOps),
+	D(ImplicitOps), D(ImplicitOps), D(Group | Group4), D(Group | Group5),
 };
 
 static struct opcode twobyte_table[256] = {
 	/* 0x00 - 0x0F */
-	0, Group | GroupDual | Group7, 0, 0,
-	0, ImplicitOps, ImplicitOps | Priv, 0,
-	ImplicitOps | Priv, ImplicitOps | Priv, 0, 0,
-	0, ImplicitOps | ModRM, 0, 0,
+	N, D(Group | GroupDual | Group7), N, N,
+	N, D(ImplicitOps), D(ImplicitOps | Priv), N,
+	D(ImplicitOps | Priv), D(ImplicitOps | Priv), N, N,
+	N, D(ImplicitOps | ModRM), N, N,
 	/* 0x10 - 0x1F */
-	0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
 	/* 0x20 - 0x2F */
-	ModRM | ImplicitOps | Priv, ModRM | Priv,
-	ModRM | ImplicitOps | Priv, ModRM | Priv,
-	0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
+	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
+	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
+	N, N, N, N,
+	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
-	ImplicitOps | Priv, 0, ImplicitOps | Priv, 0,
-	ImplicitOps, ImplicitOps | Priv, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
+	D(ImplicitOps | Priv), N, D(ImplicitOps | Priv), N,
+	D(ImplicitOps), D(ImplicitOps | Priv), N, N,
+	N, N, N, N, N, N, N, N,
 	/* 0x40 - 0x4F */
-	X16(DstReg | SrcMem | ModRM | Mov),
+	X16(D(DstReg | SrcMem | ModRM | Mov)),
 	/* 0x50 - 0x5F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
 	/* 0x60 - 0x6F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
 	/* 0x70 - 0x7F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
 	/* 0x80 - 0x8F */
-	X16(SrcImm),
+	X16(D(SrcImm)),
 	/* 0x90 - 0x9F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
 	/* 0xA0 - 0xA7 */
-	ImplicitOps | Stack, ImplicitOps | Stack,
-	0, DstMem | SrcReg | ModRM | BitOp,
-	DstMem | SrcReg | Src2ImmByte | ModRM,
-	DstMem | SrcReg | Src2CL | ModRM, 0, 0,
+	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
+	N, D(DstMem | SrcReg | ModRM | BitOp),
+	D(DstMem | SrcReg | Src2ImmByte | ModRM),
+	D(DstMem | SrcReg | Src2CL | ModRM), N, N,
 	/* 0xA8 - 0xAF */
-	ImplicitOps | Stack, ImplicitOps | Stack,
-	0, DstMem | SrcReg | ModRM | BitOp | Lock,
-	DstMem | SrcReg | Src2ImmByte | ModRM,
-	DstMem | SrcReg | Src2CL | ModRM,
-	ModRM, 0,
+	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
+	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
+	D(DstMem | SrcReg | Src2ImmByte | ModRM),
+	D(DstMem | SrcReg | Src2CL | ModRM),
+	D(ModRM), N,
 	/* 0xB0 - 0xB7 */
-	ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock,
-	0, DstMem | SrcReg | ModRM | BitOp | Lock,
-	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
-	    DstReg | SrcMem16 | ModRM | Mov,
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
+	N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov),
+	    D(DstReg | SrcMem16 | ModRM | Mov),
 	/* 0xB8 - 0xBF */
-	0, 0,
-	Group | Group8, DstMem | SrcReg | ModRM | BitOp | Lock,
-	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
-	    DstReg | SrcMem16 | ModRM | Mov,
+	N, N,
+	D(Group | Group8), D(DstMem | SrcReg | ModRM | BitOp | Lock),
+	N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov),
+	    D(DstReg | SrcMem16 | ModRM | Mov),
 	/* 0xC0 - 0xCF */
-	0, 0, 0, DstMem | SrcReg | ModRM | Mov,
-	0, 0, 0, Group | GroupDual | Group9,
-	0, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, D(DstMem | SrcReg | ModRM | Mov),
+	N, N, N, D(Group | GroupDual | Group9),
+	N, N, N, N, N, N, N, N,
 	/* 0xD0 - 0xDF */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
 	/* 0xE0 - 0xEF */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
 	/* 0xF0 - 0xFF */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N
 };
 
 static struct opcode group_table[] = {
 	[Group1*8] =
-	X7(Lock), 0,
+	X7(D(Lock)), N,
 	[Group1A*8] =
-	DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0,
+	D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N,
 	[Group3*8] =
-	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
-	DstMem | SrcNone | ModRM | Lock, DstMem | SrcNone | ModRM | Lock,
-	X4(Undefined),
+	D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM),
+	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
+	X4(D(Undefined)),
 	[Group4*8] =
-	ByteOp | DstMem | SrcNone | ModRM | Lock, ByteOp | DstMem | SrcNone | ModRM | Lock,
-	0, 0, 0, 0, 0, 0,
+	D(ByteOp | DstMem | SrcNone | ModRM | Lock), D(ByteOp | DstMem | SrcNone | ModRM | Lock),
+	N, N, N, N, N, N,
 	[Group5*8] =
-	DstMem | SrcNone | ModRM | Lock, DstMem | SrcNone | ModRM | Lock,
-	SrcMem | ModRM | Stack, 0,
-	SrcMem | ModRM | Stack, SrcMemFAddr | ModRM | ImplicitOps,
-	SrcMem | ModRM | Stack, 0,
+	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
+	D(SrcMem | ModRM | Stack), N,
+	D(SrcMem | ModRM | Stack), D(SrcMemFAddr | ModRM | ImplicitOps),
+	D(SrcMem | ModRM | Stack), N,
 	[Group7*8] =
-	0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv,
-	SrcNone | ModRM | DstMem | Mov, 0,
-	SrcMem16 | ModRM | Mov | Priv, SrcMem | ModRM | ByteOp | Priv,
+	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
+	D(SrcNone | ModRM | DstMem | Mov), N,
+	D(SrcMem16 | ModRM | Mov | Priv), D(SrcMem | ModRM | ByteOp | Priv),
 	[Group8*8] =
-	0, 0, 0, 0,
-	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock,
-	DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock,
+	N, N, N, N,
+	D(DstMem | SrcImmByte | ModRM), D(DstMem | SrcImmByte | ModRM | Lock),
+	D(DstMem | SrcImmByte | ModRM | Lock), D(DstMem | SrcImmByte | ModRM | Lock),
 	[Group9*8] =
-	0, DstMem64 | ModRM | Lock, 0, 0, 0, 0, 0, 0,
+	N, D(DstMem64 | ModRM | Lock), N, N, N, N, N, N,
 };
 
 static struct opcode group2_table[] = {
 	[Group7*8] =
-	SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM | Priv,
-	SrcNone | ModRM | DstMem | Mov, 0,
-	SrcMem16 | ModRM | Mov | Priv, 0,
+	D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
+	D(SrcNone | ModRM | DstMem | Mov), N,
+	D(SrcMem16 | ModRM | Mov | Priv), N,
 	[Group9*8] =
-	0, 0, 0, 0, 0, 0, 0, 0,
+	N, N, N, N, N, N, N, N,
 };
 
+#undef D
+#undef N
+
 /* EFLAGS bit definitions. */
 #define EFLG_ID (1<<21)
 #define EFLG_VIP (1<<20)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/22] KVM: x86 emulator: move group tables to top
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (2 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 03/22] KVM: x86 emulator: Add wrappers for easily defining opcodes Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 05/22] KVM: x86 emulator: reserve group code 0 Avi Kivity
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

No code changes.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   76 ++++++++++++++++++++++++------------------------
 1 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index cd8a219..91359b5 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -115,6 +115,44 @@ struct opcode {
 #define D(_y) { .flags = (_y) }
 #define N    D(0)
 
+static struct opcode group_table[] = {
+	[Group1*8] =
+	X7(D(Lock)), N,
+	[Group1A*8] =
+	D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N,
+	[Group3*8] =
+	D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM),
+	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
+	X4(D(Undefined)),
+	[Group4*8] =
+	D(ByteOp | DstMem | SrcNone | ModRM | Lock), D(ByteOp | DstMem | SrcNone | ModRM | Lock),
+	N, N, N, N, N, N,
+	[Group5*8] =
+	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
+	D(SrcMem | ModRM | Stack), N,
+	D(SrcMem | ModRM | Stack), D(SrcMemFAddr | ModRM | ImplicitOps),
+	D(SrcMem | ModRM | Stack), N,
+	[Group7*8] =
+	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
+	D(SrcNone | ModRM | DstMem | Mov), N,
+	D(SrcMem16 | ModRM | Mov | Priv), D(SrcMem | ModRM | ByteOp | Priv),
+	[Group8*8] =
+	N, N, N, N,
+	D(DstMem | SrcImmByte | ModRM), D(DstMem | SrcImmByte | ModRM | Lock),
+	D(DstMem | SrcImmByte | ModRM | Lock), D(DstMem | SrcImmByte | ModRM | Lock),
+	[Group9*8] =
+	N, D(DstMem64 | ModRM | Lock), N, N, N, N, N, N,
+};
+
+static struct opcode group2_table[] = {
+	[Group7*8] =
+	D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
+	D(SrcNone | ModRM | DstMem | Mov), N,
+	D(SrcMem16 | ModRM | Mov | Priv), N,
+	[Group9*8] =
+	N, N, N, N, N, N, N, N,
+};
+
 static struct opcode opcode_table[256] = {
 	/* 0x00 - 0x07 */
 	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
@@ -291,44 +329,6 @@ static struct opcode twobyte_table[256] = {
 	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N
 };
 
-static struct opcode group_table[] = {
-	[Group1*8] =
-	X7(D(Lock)), N,
-	[Group1A*8] =
-	D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N,
-	[Group3*8] =
-	D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM),
-	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
-	X4(D(Undefined)),
-	[Group4*8] =
-	D(ByteOp | DstMem | SrcNone | ModRM | Lock), D(ByteOp | DstMem | SrcNone | ModRM | Lock),
-	N, N, N, N, N, N,
-	[Group5*8] =
-	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
-	D(SrcMem | ModRM | Stack), N,
-	D(SrcMem | ModRM | Stack), D(SrcMemFAddr | ModRM | ImplicitOps),
-	D(SrcMem | ModRM | Stack), N,
-	[Group7*8] =
-	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
-	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv), D(SrcMem | ModRM | ByteOp | Priv),
-	[Group8*8] =
-	N, N, N, N,
-	D(DstMem | SrcImmByte | ModRM), D(DstMem | SrcImmByte | ModRM | Lock),
-	D(DstMem | SrcImmByte | ModRM | Lock), D(DstMem | SrcImmByte | ModRM | Lock),
-	[Group9*8] =
-	N, D(DstMem64 | ModRM | Lock), N, N, N, N, N, N,
-};
-
-static struct opcode group2_table[] = {
-	[Group7*8] =
-	D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
-	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv), N,
-	[Group9*8] =
-	N, N, N, N, N, N, N, N,
-};
-
 #undef D
 #undef N
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/22] KVM: x86 emulator: reserve group code 0
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (3 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 04/22] KVM: x86 emulator: move group tables to top Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 06/22] KVM: x86 emulator: allow specifying group directly in opcode Avi Kivity
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

We'll be using that to distinguish between new-style and old-style groups.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 91359b5..b0100f6 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -105,7 +105,7 @@
 #define X16(x) X8(x), X8(x)
 
 enum {
-	Group1, Group1A, Group3, Group4, Group5, Group7, Group8, Group9,
+	NoGrp, Group1, Group1A, Group3, Group4, Group5, Group7, Group8, Group9,
 };
 
 struct opcode {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/22] KVM: x86 emulator: allow specifying group directly in opcode
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (4 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 05/22] KVM: x86 emulator: reserve group code 0 Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 07/22] KVM: x86 emulator: convert group 1 to new style Avi Kivity
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Instead of having a group number, store the group table pointer directly in
the opcode.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   47 ++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index b0100f6..ee5b38d 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -110,10 +110,21 @@ enum {
 
 struct opcode {
 	u32 flags;
+	union {
+		struct opcode *group;
+		struct group_dual *gdual;
+	} u;
+};
+
+struct group_dual {
+	struct opcode mod012[8];
+	struct opcode mod3[8];
 };
 
 #define D(_y) { .flags = (_y) }
 #define N    D(0)
+#define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
+#define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
 
 static struct opcode group_table[] = {
 	[Group1*8] =
@@ -331,6 +342,8 @@ static struct opcode twobyte_table[256] = {
 
 #undef D
 #undef N
+#undef G
+#undef GD
 
 /* EFLAGS bit definitions. */
 #define EFLG_ID (1<<21)
@@ -927,8 +940,8 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 	struct decode_cache *c = &ctxt->decode;
 	int rc = X86EMUL_CONTINUE;
 	int mode = ctxt->mode;
-	int def_op_bytes, def_ad_bytes, group, dual;
-
+	int def_op_bytes, def_ad_bytes, group, dual, goffset;
+	struct opcode opcode, *g_mod012, *g_mod3;
 
 	/* we cannot decode insn before we complete previous rep insn */
 	WARN_ON(ctxt->restart);
@@ -1015,15 +1028,16 @@ done_prefixes:
 			c->op_bytes = 8;	/* REX.W */
 
 	/* Opcode byte(s). */
-	c->d = opcode_table[c->b].flags;
-	if (c->d == 0) {
+	opcode = opcode_table[c->b];
+	if (opcode.flags == 0) {
 		/* Two-byte opcode? */
 		if (c->b == 0x0f) {
 			c->twobyte = 1;
 			c->b = insn_fetch(u8, 1, c->eip);
-			c->d = twobyte_table[c->b].flags;
+			opcode = twobyte_table[c->b];
 		}
 	}
+	c->d = opcode.flags;
 
 	if (c->d & Group) {
 		group = c->d & GroupMask;
@@ -1031,12 +1045,27 @@ done_prefixes:
 		c->modrm = insn_fetch(u8, 1, c->eip);
 		--c->eip;
 
-		group = (group << 3) + ((c->modrm >> 3) & 7);
+		if (group) {
+			g_mod012 = g_mod3 = &group_table[group * 8];
+			if (c->d & GroupDual)
+				g_mod3 = &group2_table[group * 8];
+		} else {
+			if (c->d & GroupDual) {
+				g_mod012 = opcode.u.gdual->mod012;
+				g_mod3 = opcode.u.gdual->mod3;
+			} else
+				g_mod012 = g_mod3 = opcode.u.group;
+		}
+
 		c->d &= ~(Group | GroupDual | GroupMask);
-		if (dual && (c->modrm >> 6) == 3)
-			c->d |= group2_table[group].flags;
+
+		goffset = (c->modrm >> 3) & 7;
+
+		if ((c->modrm >> 6) == 3)
+			opcode = g_mod3[goffset];
 		else
-			c->d |= group_table[group].flags;
+			opcode = g_mod012[goffset];
+		c->d |= opcode.flags;
 	}
 
 	/* Unrecognised? */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/22] KVM: x86 emulator: convert group 1 to new style
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (5 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 06/22] KVM: x86 emulator: allow specifying group directly in opcode Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 08/22] KVM: x86 emulator: convert group 1A " Avi Kivity
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index ee5b38d..139a324 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -105,7 +105,7 @@
 #define X16(x) X8(x), X8(x)
 
 enum {
-	NoGrp, Group1, Group1A, Group3, Group4, Group5, Group7, Group8, Group9,
+	NoGrp, Group1A, Group3, Group4, Group5, Group7, Group8, Group9,
 };
 
 struct opcode {
@@ -126,9 +126,11 @@ struct group_dual {
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
 #define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
 
+static struct opcode group1[] = {
+	X7(D(Lock)), N
+};
+
 static struct opcode group_table[] = {
-	[Group1*8] =
-	X7(D(Lock)), N,
 	[Group1A*8] =
 	D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N,
 	[Group3*8] =
@@ -219,10 +221,10 @@ static struct opcode opcode_table[256] = {
 	/* 0x70 - 0x7F */
 	X16(D(SrcImmByte)),
 	/* 0x80 - 0x87 */
-	D(ByteOp | DstMem | SrcImm | ModRM | Group | Group1),
-	D(DstMem | SrcImm | ModRM | Group | Group1),
-	D(ByteOp | DstMem | SrcImm | ModRM | No64 | Group | Group1),
-	D(DstMem | SrcImmByte | ModRM | Group | Group1),
+	G(ByteOp | DstMem | SrcImm | ModRM | Group, group1),
+	G(DstMem | SrcImm | ModRM | Group, group1),
+	G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1),
+	G(DstMem | SrcImmByte | ModRM | Group, group1),
 	D(ByteOp | DstMem | SrcReg | ModRM), D(DstMem | SrcReg | ModRM),
 	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
 	/* 0x88 - 0x8F */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/22] KVM: x86 emulator: convert group 1A to new style
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (6 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 07/22] KVM: x86 emulator: convert group 1 to new style Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 09/22] KVM: x86 emulator: convert group 3 " Avi Kivity
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 139a324..637f2c9 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -105,7 +105,7 @@
 #define X16(x) X8(x), X8(x)
 
 enum {
-	NoGrp, Group1A, Group3, Group4, Group5, Group7, Group8, Group9,
+	NoGrp, Group3, Group4, Group5, Group7, Group8, Group9,
 };
 
 struct opcode {
@@ -130,9 +130,11 @@ static struct opcode group1[] = {
 	X7(D(Lock)), N
 };
 
-static struct opcode group_table[] = {
-	[Group1A*8] =
+static struct opcode group1A[] = {
 	D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N,
+};
+
+static struct opcode group_table[] = {
 	[Group3*8] =
 	D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM),
 	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
@@ -231,7 +233,7 @@ static struct opcode opcode_table[256] = {
 	D(ByteOp | DstMem | SrcReg | ModRM | Mov), D(DstMem | SrcReg | ModRM | Mov),
 	D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem | ModRM | Mov),
 	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | DstReg),
-	D(ImplicitOps | SrcMem16 | ModRM), D(Group | Group1A),
+	D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
 	/* 0x90 - 0x97 */
 	D(DstReg), D(DstReg), D(DstReg), D(DstReg),	D(DstReg), D(DstReg), D(DstReg), D(DstReg),
 	/* 0x98 - 0x9F */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/22] KVM: x86 emulator: convert group 3 to new style
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (7 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 08/22] KVM: x86 emulator: convert group 1A " Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 10/22] KVM: x86 emulator: convert group 4 " Avi Kivity
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 637f2c9..6fee257 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -105,7 +105,7 @@
 #define X16(x) X8(x), X8(x)
 
 enum {
-	NoGrp, Group3, Group4, Group5, Group7, Group8, Group9,
+	NoGrp, Group4, Group5, Group7, Group8, Group9,
 };
 
 struct opcode {
@@ -134,11 +134,13 @@ static struct opcode group1A[] = {
 	D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N,
 };
 
-static struct opcode group_table[] = {
-	[Group3*8] =
+static struct opcode group3[] = {
 	D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM),
 	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
 	X4(D(Undefined)),
+};
+
+static struct opcode group_table[] = {
 	[Group4*8] =
 	D(ByteOp | DstMem | SrcNone | ModRM | Lock), D(ByteOp | DstMem | SrcNone | ModRM | Lock),
 	N, N, N, N, N, N,
@@ -276,7 +278,7 @@ static struct opcode opcode_table[256] = {
 	D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc),
 	/* 0xF0 - 0xF7 */
 	N, N, N, N,
-	D(ImplicitOps | Priv), D(ImplicitOps), D(ByteOp | Group | Group3), D(Group | Group3),
+	D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3),
 	/* 0xF8 - 0xFF */
 	D(ImplicitOps), N, D(ImplicitOps), D(ImplicitOps),
 	D(ImplicitOps), D(ImplicitOps), D(Group | Group4), D(Group | Group5),
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/22] KVM: x86 emulator: convert group 4 to new style
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (8 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 09/22] KVM: x86 emulator: convert group 3 " Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 11/22] KVM: x86 emulator: convert group 5 " Avi Kivity
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 6fee257..afdfd86 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -105,7 +105,7 @@
 #define X16(x) X8(x), X8(x)
 
 enum {
-	NoGrp, Group4, Group5, Group7, Group8, Group9,
+	NoGrp, Group5, Group7, Group8, Group9,
 };
 
 struct opcode {
@@ -140,10 +140,12 @@ static struct opcode group3[] = {
 	X4(D(Undefined)),
 };
 
-static struct opcode group_table[] = {
-	[Group4*8] =
+static struct opcode group4[] = {
 	D(ByteOp | DstMem | SrcNone | ModRM | Lock), D(ByteOp | DstMem | SrcNone | ModRM | Lock),
 	N, N, N, N, N, N,
+};
+
+static struct opcode group_table[] = {
 	[Group5*8] =
 	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
 	D(SrcMem | ModRM | Stack), N,
@@ -281,7 +283,7 @@ static struct opcode opcode_table[256] = {
 	D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3),
 	/* 0xF8 - 0xFF */
 	D(ImplicitOps), N, D(ImplicitOps), D(ImplicitOps),
-	D(ImplicitOps), D(ImplicitOps), D(Group | Group4), D(Group | Group5),
+	D(ImplicitOps), D(ImplicitOps), G(0, group4), D(Group | Group5),
 };
 
 static struct opcode twobyte_table[256] = {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 11/22] KVM: x86 emulator: convert group 5 to new style
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (9 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 10/22] KVM: x86 emulator: convert group 4 " Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 12/22] KVM: x86 emulator: convert group 7 " Avi Kivity
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index afdfd86..39745e5 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -105,7 +105,7 @@
 #define X16(x) X8(x), X8(x)
 
 enum {
-	NoGrp, Group5, Group7, Group8, Group9,
+	NoGrp, Group7, Group8, Group9,
 };
 
 struct opcode {
@@ -145,12 +145,14 @@ static struct opcode group4[] = {
 	N, N, N, N, N, N,
 };
 
-static struct opcode group_table[] = {
-	[Group5*8] =
+static struct opcode group5[] = {
 	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
 	D(SrcMem | ModRM | Stack), N,
 	D(SrcMem | ModRM | Stack), D(SrcMemFAddr | ModRM | ImplicitOps),
 	D(SrcMem | ModRM | Stack), N,
+};
+
+static struct opcode group_table[] = {
 	[Group7*8] =
 	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
 	D(SrcNone | ModRM | DstMem | Mov), N,
@@ -283,7 +285,7 @@ static struct opcode opcode_table[256] = {
 	D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3),
 	/* 0xF8 - 0xFF */
 	D(ImplicitOps), N, D(ImplicitOps), D(ImplicitOps),
-	D(ImplicitOps), D(ImplicitOps), G(0, group4), D(Group | Group5),
+	D(ImplicitOps), D(ImplicitOps), G(0, group4), G(0, group5),
 };
 
 static struct opcode twobyte_table[256] = {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 12/22] KVM: x86 emulator: convert group 7 to new style
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (10 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 11/22] KVM: x86 emulator: convert group 5 " Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 13/22] KVM: x86 emulator: convert group 8 " Avi Kivity
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 39745e5..52995e3 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -105,7 +105,7 @@
 #define X16(x) X8(x), X8(x)
 
 enum {
-	NoGrp, Group7, Group8, Group9,
+	NoGrp, Group8, Group9,
 };
 
 struct opcode {
@@ -152,11 +152,17 @@ static struct opcode group5[] = {
 	D(SrcMem | ModRM | Stack), N,
 };
 
-static struct opcode group_table[] = {
-	[Group7*8] =
+static struct group_dual group7 = { {
 	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
 	D(SrcNone | ModRM | DstMem | Mov), N,
 	D(SrcMem16 | ModRM | Mov | Priv), D(SrcMem | ModRM | ByteOp | Priv),
+}, {
+	D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
+	D(SrcNone | ModRM | DstMem | Mov), N,
+	D(SrcMem16 | ModRM | Mov | Priv), N,
+} };
+
+static struct opcode group_table[] = {
 	[Group8*8] =
 	N, N, N, N,
 	D(DstMem | SrcImmByte | ModRM), D(DstMem | SrcImmByte | ModRM | Lock),
@@ -166,10 +172,6 @@ static struct opcode group_table[] = {
 };
 
 static struct opcode group2_table[] = {
-	[Group7*8] =
-	D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
-	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv), N,
 	[Group9*8] =
 	N, N, N, N, N, N, N, N,
 };
@@ -290,7 +292,7 @@ static struct opcode opcode_table[256] = {
 
 static struct opcode twobyte_table[256] = {
 	/* 0x00 - 0x0F */
-	N, D(Group | GroupDual | Group7), N, N,
+	N, GD(0, &group7), N, N,
 	N, D(ImplicitOps), D(ImplicitOps | Priv), N,
 	D(ImplicitOps | Priv), D(ImplicitOps | Priv), N, N,
 	N, D(ImplicitOps | ModRM), N, N,
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 13/22] KVM: x86 emulator: convert group 8 to new style
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (11 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 12/22] KVM: x86 emulator: convert group 7 " Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 14/22] KVM: x86 emulator: convert group 9 " Avi Kivity
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 52995e3..adddf32 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -105,7 +105,7 @@
 #define X16(x) X8(x), X8(x)
 
 enum {
-	NoGrp, Group8, Group9,
+	NoGrp, Group9,
 };
 
 struct opcode {
@@ -162,11 +162,13 @@ static struct group_dual group7 = { {
 	D(SrcMem16 | ModRM | Mov | Priv), N,
 } };
 
-static struct opcode group_table[] = {
-	[Group8*8] =
+static struct opcode group8[] = {
 	N, N, N, N,
 	D(DstMem | SrcImmByte | ModRM), D(DstMem | SrcImmByte | ModRM | Lock),
 	D(DstMem | SrcImmByte | ModRM | Lock), D(DstMem | SrcImmByte | ModRM | Lock),
+};
+
+static struct opcode group_table[] = {
 	[Group9*8] =
 	N, D(DstMem64 | ModRM | Lock), N, N, N, N, N, N,
 };
@@ -337,7 +339,7 @@ static struct opcode twobyte_table[256] = {
 	    D(DstReg | SrcMem16 | ModRM | Mov),
 	/* 0xB8 - 0xBF */
 	N, N,
-	D(Group | Group8), D(DstMem | SrcReg | ModRM | BitOp | Lock),
+	G(0, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock),
 	N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov),
 	    D(DstReg | SrcMem16 | ModRM | Mov),
 	/* 0xC0 - 0xCF */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 14/22] KVM: x86 emulator: convert group 9 to new style
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (12 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 13/22] KVM: x86 emulator: convert group 8 " Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 15/22] KVM: x86 emulator: drop support for old-style groups Avi Kivity
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index adddf32..42bd255 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -105,7 +105,7 @@
 #define X16(x) X8(x), X8(x)
 
 enum {
-	NoGrp, Group9,
+	NoGrp,
 };
 
 struct opcode {
@@ -168,14 +168,16 @@ static struct opcode group8[] = {
 	D(DstMem | SrcImmByte | ModRM | Lock), D(DstMem | SrcImmByte | ModRM | Lock),
 };
 
-static struct opcode group_table[] = {
-	[Group9*8] =
+static struct group_dual group9 = { {
 	N, D(DstMem64 | ModRM | Lock), N, N, N, N, N, N,
+}, {
+	N, N, N, N, N, N, N, N,
+} };
+
+static struct opcode group_table[] = {
 };
 
 static struct opcode group2_table[] = {
-	[Group9*8] =
-	N, N, N, N, N, N, N, N,
 };
 
 static struct opcode opcode_table[256] = {
@@ -344,7 +346,7 @@ static struct opcode twobyte_table[256] = {
 	    D(DstReg | SrcMem16 | ModRM | Mov),
 	/* 0xC0 - 0xCF */
 	N, N, N, D(DstMem | SrcReg | ModRM | Mov),
-	N, N, N, D(Group | GroupDual | Group9),
+	N, N, N, GD(0, &group9),
 	N, N, N, N, N, N, N, N,
 	/* 0xD0 - 0xDF */
 	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 15/22] KVM: x86 emulator: drop support for old-style groups
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (13 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 14/22] KVM: x86 emulator: convert group 9 " Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 16/22] KVM: x86 emulator: move ByteOp and Dst back to bits 0:3 Avi Kivity
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   32 +++++++-------------------------
 1 files changed, 7 insertions(+), 25 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 42bd255..bb05687 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -82,7 +82,6 @@
 #define Stack       (1<<13)     /* Stack instruction (push/pop) */
 #define Group       (1<<14)     /* Bits 3:5 of modrm byte extend opcode */
 #define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
-#define GroupMask   0x0f        /* Group number stored in bits 0:3 */
 /* Misc flags */
 #define Undefined   (1<<25) /* No Such Instruction */
 #define Lock        (1<<26) /* lock prefix is allowed for the instruction */
@@ -104,10 +103,6 @@
 #define X8(x) X4(x), X4(x)
 #define X16(x) X8(x), X8(x)
 
-enum {
-	NoGrp,
-};
-
 struct opcode {
 	u32 flags;
 	union {
@@ -174,12 +169,6 @@ static struct group_dual group9 = { {
 	N, N, N, N, N, N, N, N,
 } };
 
-static struct opcode group_table[] = {
-};
-
-static struct opcode group2_table[] = {
-};
-
 static struct opcode opcode_table[256] = {
 	/* 0x00 - 0x07 */
 	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
@@ -956,7 +945,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 	struct decode_cache *c = &ctxt->decode;
 	int rc = X86EMUL_CONTINUE;
 	int mode = ctxt->mode;
-	int def_op_bytes, def_ad_bytes, group, dual, goffset;
+	int def_op_bytes, def_ad_bytes, dual, goffset;
 	struct opcode opcode, *g_mod012, *g_mod3;
 
 	/* we cannot decode insn before we complete previous rep insn */
@@ -1056,24 +1045,17 @@ done_prefixes:
 	c->d = opcode.flags;
 
 	if (c->d & Group) {
-		group = c->d & GroupMask;
 		dual = c->d & GroupDual;
 		c->modrm = insn_fetch(u8, 1, c->eip);
 		--c->eip;
 
-		if (group) {
-			g_mod012 = g_mod3 = &group_table[group * 8];
-			if (c->d & GroupDual)
-				g_mod3 = &group2_table[group * 8];
-		} else {
-			if (c->d & GroupDual) {
-				g_mod012 = opcode.u.gdual->mod012;
-				g_mod3 = opcode.u.gdual->mod3;
-			} else
-				g_mod012 = g_mod3 = opcode.u.group;
-		}
+		if (c->d & GroupDual) {
+			g_mod012 = opcode.u.gdual->mod012;
+			g_mod3 = opcode.u.gdual->mod3;
+		} else
+			g_mod012 = g_mod3 = opcode.u.group;
 
-		c->d &= ~(Group | GroupDual | GroupMask);
+		c->d &= ~(Group | GroupDual);
 
 		goffset = (c->modrm >> 3) & 7;
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 16/22] KVM: x86 emulator: move ByteOp and Dst back to bits 0:3
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (14 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 15/22] KVM: x86 emulator: drop support for old-style groups Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 17/22] KVM: x86 emulator: store x86_emulate_ops in emulation context Avi Kivity
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Now that the group index no longer exists, the space is free.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index bb05687..b10f270 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -46,15 +46,15 @@
  */
 
 /* Operand sizes: 8-bit operands or specified/overridden size. */
-#define ByteOp      (1<<16)	/* 8-bit operands. */
+#define ByteOp      (1<<0)	/* 8-bit operands. */
 /* Destination operand type. */
-#define ImplicitOps (1<<17)	/* Implicit in opcode. No generic decode. */
-#define DstReg      (2<<17)	/* Register operand. */
-#define DstMem      (3<<17)	/* Memory operand. */
-#define DstAcc      (4<<17)	/* Destination Accumulator */
-#define DstDI       (5<<17)	/* Destination is in ES:(E)DI */
-#define DstMem64    (6<<17)	/* 64bit memory operand */
-#define DstMask     (7<<17)
+#define ImplicitOps (1<<1)	/* Implicit in opcode. No generic decode. */
+#define DstReg      (2<<1)	/* Register operand. */
+#define DstMem      (3<<1)	/* Memory operand. */
+#define DstAcc      (4<<1)	/* Destination Accumulator */
+#define DstDI       (5<<1)	/* Destination is in ES:(E)DI */
+#define DstMem64    (6<<1)	/* 64bit memory operand */
+#define DstMask     (7<<1)
 /* Source operand type. */
 #define SrcNone     (0<<4)	/* No source operand. */
 #define SrcImplicit (0<<4)	/* Source operand is implicit in the opcode. */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 17/22] KVM: x86 emulator: store x86_emulate_ops in emulation context
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (15 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 16/22] KVM: x86 emulator: move ByteOp and Dst back to bits 0:3 Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 18/22] KVM: x86 emulator: allow storing emulator execution function in decode tables Avi Kivity
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

It doesn't ever change, so we don't need to pass it around everywhere.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/include/asm/kvm_emulate.h |    9 ++++-----
 arch/x86/kvm/emulate.c             |    8 +++++---
 arch/x86/kvm/x86.c                 |    7 ++++---
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 51cfd73..daf4477 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -203,6 +203,8 @@ struct decode_cache {
 };
 
 struct x86_emulate_ctxt {
+	struct x86_emulate_ops *ops;
+
 	/* Register state before/after emulation. */
 	struct kvm_vcpu *vcpu;
 
@@ -244,12 +246,9 @@ struct x86_emulate_ctxt {
 #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
 #endif
 
-int x86_decode_insn(struct x86_emulate_ctxt *ctxt,
-		    struct x86_emulate_ops *ops);
-int x86_emulate_insn(struct x86_emulate_ctxt *ctxt,
-		     struct x86_emulate_ops *ops);
+int x86_decode_insn(struct x86_emulate_ctxt *ctxt);
+int x86_emulate_insn(struct x86_emulate_ctxt *ctxt);
 int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
-			 struct x86_emulate_ops *ops,
 			 u16 tss_selector, int reason,
 			 bool has_error_code, u32 error_code);
 
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index b10f270..f3f6fd9 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -940,8 +940,9 @@ done:
 }
 
 int
-x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+x86_decode_insn(struct x86_emulate_ctxt *ctxt)
 {
+	struct x86_emulate_ops *ops = ctxt->ops;
 	struct decode_cache *c = &ctxt->decode;
 	int rc = X86EMUL_CONTINUE;
 	int mode = ctxt->mode;
@@ -2512,10 +2513,10 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
 }
 
 int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
-			 struct x86_emulate_ops *ops,
 			 u16 tss_selector, int reason,
 			 bool has_error_code, u32 error_code)
 {
+	struct x86_emulate_ops *ops = ctxt->ops;
 	struct decode_cache *c = &ctxt->decode;
 	int rc;
 
@@ -2545,8 +2546,9 @@ static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base,
 }
 
 int
-x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 {
+	struct x86_emulate_ops *ops = ctxt->ops;
 	u64 msr_data;
 	struct decode_cache *c = &ctxt->decode;
 	int rc = X86EMUL_CONTINUE;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 76fbc32..7308bb8 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3998,7 +3998,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
 		vcpu->arch.emulate_ctxt.interruptibility = 0;
 		vcpu->arch.emulate_ctxt.exception = -1;
 
-		r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
+		r = x86_decode_insn(&vcpu->arch.emulate_ctxt);
 		trace_kvm_emulate_insn_start(vcpu);
 
 		/* Only allow emulation of specific instructions on #UD
@@ -4048,7 +4048,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
 	memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
 
 restart:
-	r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
+	r = x86_emulate_insn(&vcpu->arch.emulate_ctxt);
 
 	if (r) { /* emulation failed */
 		if (reexecute_instruction(vcpu, cr2))
@@ -5067,7 +5067,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason,
 	memset(c, 0, sizeof(struct decode_cache));
 	memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
 
-	ret = emulator_task_switch(&vcpu->arch.emulate_ctxt, &emulate_ops,
+	ret = emulator_task_switch(&vcpu->arch.emulate_ctxt,
 				   tss_selector, reason, has_error_code,
 				   error_code);
 
@@ -5424,6 +5424,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 	BUG_ON(vcpu->kvm == NULL);
 	kvm = vcpu->kvm;
 
+	vcpu->arch.emulate_ctxt.ops = &emulate_ops;
 	vcpu->arch.mmu.root_hpa = INVALID_PAGE;
 	if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu))
 		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 18/22] KVM: x86 emulator: allow storing emulator execution function in decode tables
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (16 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 17/22] KVM: x86 emulator: store x86_emulate_ops in emulation context Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 19/22] KVM: x86 emulator: move x86_decode_insn() downwards Avi Kivity
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Instead of looking up the opcode twice (once for decode flags, once for
the big execution switch) look up both flags and function in the decode tables.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/include/asm/kvm_emulate.h |    1 +
 arch/x86/kvm/emulate.c             |   12 ++++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index daf4477..f397b79 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -185,6 +185,7 @@ struct decode_cache {
 	bool has_seg_override;
 	u8 seg_override;
 	unsigned int d;
+	int (*execute)(struct x86_emulate_ctxt *ctxt);
 	unsigned long regs[NR_VCPU_REGS];
 	unsigned long eip;
 	/* modrm */
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index f3f6fd9..8b19da2 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -106,6 +106,7 @@
 struct opcode {
 	u32 flags;
 	union {
+		int (*execute)(struct x86_emulate_ctxt *ctxt);
 		struct opcode *group;
 		struct group_dual *gdual;
 	} u;
@@ -120,6 +121,7 @@ struct group_dual {
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
 #define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
+#define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
 
 static struct opcode group1[] = {
 	X7(D(Lock)), N
@@ -349,6 +351,7 @@ static struct opcode twobyte_table[256] = {
 #undef N
 #undef G
 #undef GD
+#undef I
 
 /* EFLAGS bit definitions. */
 #define EFLG_ID (1<<21)
@@ -1067,6 +1070,8 @@ done_prefixes:
 		c->d |= opcode.flags;
 	}
 
+	c->execute = opcode.u.execute;
+
 	/* Unrecognised? */
 	if (c->d == 0 || (c->d & Undefined)) {
 		DPRINTF("Cannot emulate %02x\n", c->b);
@@ -2631,6 +2636,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 
 special_insn:
 
+	if (c->execute) {
+		rc = c->execute(ctxt);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+		goto writeback;
+	}
+
 	if (c->twobyte)
 		goto twobyte_insn;
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 19/22] KVM: x86 emulator: move x86_decode_insn() downwards
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (17 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 18/22] KVM: x86 emulator: allow storing emulator execution function in decode tables Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 20/22] KVM: x86 emulator: move decode tables downwards Avi Kivity
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

No code changes.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |  744 ++++++++++++++++++++++++------------------------
 1 files changed, 372 insertions(+), 372 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 8b19da2..620525f 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -942,378 +942,6 @@ done:
 	return rc;
 }
 
-int
-x86_decode_insn(struct x86_emulate_ctxt *ctxt)
-{
-	struct x86_emulate_ops *ops = ctxt->ops;
-	struct decode_cache *c = &ctxt->decode;
-	int rc = X86EMUL_CONTINUE;
-	int mode = ctxt->mode;
-	int def_op_bytes, def_ad_bytes, dual, goffset;
-	struct opcode opcode, *g_mod012, *g_mod3;
-
-	/* we cannot decode insn before we complete previous rep insn */
-	WARN_ON(ctxt->restart);
-
-	c->eip = ctxt->eip;
-	c->fetch.start = c->fetch.end = c->eip;
-	ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS);
-
-	switch (mode) {
-	case X86EMUL_MODE_REAL:
-	case X86EMUL_MODE_VM86:
-	case X86EMUL_MODE_PROT16:
-		def_op_bytes = def_ad_bytes = 2;
-		break;
-	case X86EMUL_MODE_PROT32:
-		def_op_bytes = def_ad_bytes = 4;
-		break;
-#ifdef CONFIG_X86_64
-	case X86EMUL_MODE_PROT64:
-		def_op_bytes = 4;
-		def_ad_bytes = 8;
-		break;
-#endif
-	default:
-		return -1;
-	}
-
-	c->op_bytes = def_op_bytes;
-	c->ad_bytes = def_ad_bytes;
-
-	/* Legacy prefixes. */
-	for (;;) {
-		switch (c->b = insn_fetch(u8, 1, c->eip)) {
-		case 0x66:	/* operand-size override */
-			/* switch between 2/4 bytes */
-			c->op_bytes = def_op_bytes ^ 6;
-			break;
-		case 0x67:	/* address-size override */
-			if (mode == X86EMUL_MODE_PROT64)
-				/* switch between 4/8 bytes */
-				c->ad_bytes = def_ad_bytes ^ 12;
-			else
-				/* switch between 2/4 bytes */
-				c->ad_bytes = def_ad_bytes ^ 6;
-			break;
-		case 0x26:	/* ES override */
-		case 0x2e:	/* CS override */
-		case 0x36:	/* SS override */
-		case 0x3e:	/* DS override */
-			set_seg_override(c, (c->b >> 3) & 3);
-			break;
-		case 0x64:	/* FS override */
-		case 0x65:	/* GS override */
-			set_seg_override(c, c->b & 7);
-			break;
-		case 0x40 ... 0x4f: /* REX */
-			if (mode != X86EMUL_MODE_PROT64)
-				goto done_prefixes;
-			c->rex_prefix = c->b;
-			continue;
-		case 0xf0:	/* LOCK */
-			c->lock_prefix = 1;
-			break;
-		case 0xf2:	/* REPNE/REPNZ */
-			c->rep_prefix = REPNE_PREFIX;
-			break;
-		case 0xf3:	/* REP/REPE/REPZ */
-			c->rep_prefix = REPE_PREFIX;
-			break;
-		default:
-			goto done_prefixes;
-		}
-
-		/* Any legacy prefix after a REX prefix nullifies its effect. */
-
-		c->rex_prefix = 0;
-	}
-
-done_prefixes:
-
-	/* REX prefix. */
-	if (c->rex_prefix)
-		if (c->rex_prefix & 8)
-			c->op_bytes = 8;	/* REX.W */
-
-	/* Opcode byte(s). */
-	opcode = opcode_table[c->b];
-	if (opcode.flags == 0) {
-		/* Two-byte opcode? */
-		if (c->b == 0x0f) {
-			c->twobyte = 1;
-			c->b = insn_fetch(u8, 1, c->eip);
-			opcode = twobyte_table[c->b];
-		}
-	}
-	c->d = opcode.flags;
-
-	if (c->d & Group) {
-		dual = c->d & GroupDual;
-		c->modrm = insn_fetch(u8, 1, c->eip);
-		--c->eip;
-
-		if (c->d & GroupDual) {
-			g_mod012 = opcode.u.gdual->mod012;
-			g_mod3 = opcode.u.gdual->mod3;
-		} else
-			g_mod012 = g_mod3 = opcode.u.group;
-
-		c->d &= ~(Group | GroupDual);
-
-		goffset = (c->modrm >> 3) & 7;
-
-		if ((c->modrm >> 6) == 3)
-			opcode = g_mod3[goffset];
-		else
-			opcode = g_mod012[goffset];
-		c->d |= opcode.flags;
-	}
-
-	c->execute = opcode.u.execute;
-
-	/* Unrecognised? */
-	if (c->d == 0 || (c->d & Undefined)) {
-		DPRINTF("Cannot emulate %02x\n", c->b);
-		return -1;
-	}
-
-	if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
-		c->op_bytes = 8;
-
-	/* ModRM and SIB bytes. */
-	if (c->d & ModRM)
-		rc = decode_modrm(ctxt, ops);
-	else if (c->d & MemAbs)
-		rc = decode_abs(ctxt, ops);
-	if (rc != X86EMUL_CONTINUE)
-		goto done;
-
-	if (!c->has_seg_override)
-		set_seg_override(c, VCPU_SREG_DS);
-
-	if (!(!c->twobyte && c->b == 0x8d))
-		c->modrm_ea += seg_override_base(ctxt, ops, c);
-
-	if (c->ad_bytes != 8)
-		c->modrm_ea = (u32)c->modrm_ea;
-
-	if (c->rip_relative)
-		c->modrm_ea += c->eip;
-
-	/*
-	 * Decode and fetch the source operand: register, memory
-	 * or immediate.
-	 */
-	switch (c->d & SrcMask) {
-	case SrcNone:
-		break;
-	case SrcReg:
-		decode_register_operand(&c->src, c, 0);
-		break;
-	case SrcMem16:
-		c->src.bytes = 2;
-		goto srcmem_common;
-	case SrcMem32:
-		c->src.bytes = 4;
-		goto srcmem_common;
-	case SrcMem:
-		c->src.bytes = (c->d & ByteOp) ? 1 :
-							   c->op_bytes;
-		/* Don't fetch the address for invlpg: it could be unmapped. */
-		if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7)
-			break;
-	srcmem_common:
-		/*
-		 * For instructions with a ModR/M byte, switch to register
-		 * access if Mod = 3.
-		 */
-		if ((c->d & ModRM) && c->modrm_mod == 3) {
-			c->src.type = OP_REG;
-			c->src.val = c->modrm_val;
-			c->src.ptr = c->modrm_ptr;
-			break;
-		}
-		c->src.type = OP_MEM;
-		c->src.ptr = (unsigned long *)c->modrm_ea;
-		c->src.val = 0;
-		break;
-	case SrcImm:
-	case SrcImmU:
-		c->src.type = OP_IMM;
-		c->src.ptr = (unsigned long *)c->eip;
-		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		if (c->src.bytes == 8)
-			c->src.bytes = 4;
-		/* NB. Immediates are sign-extended as necessary. */
-		switch (c->src.bytes) {
-		case 1:
-			c->src.val = insn_fetch(s8, 1, c->eip);
-			break;
-		case 2:
-			c->src.val = insn_fetch(s16, 2, c->eip);
-			break;
-		case 4:
-			c->src.val = insn_fetch(s32, 4, c->eip);
-			break;
-		}
-		if ((c->d & SrcMask) == SrcImmU) {
-			switch (c->src.bytes) {
-			case 1:
-				c->src.val &= 0xff;
-				break;
-			case 2:
-				c->src.val &= 0xffff;
-				break;
-			case 4:
-				c->src.val &= 0xffffffff;
-				break;
-			}
-		}
-		break;
-	case SrcImmByte:
-	case SrcImmUByte:
-		c->src.type = OP_IMM;
-		c->src.ptr = (unsigned long *)c->eip;
-		c->src.bytes = 1;
-		if ((c->d & SrcMask) == SrcImmByte)
-			c->src.val = insn_fetch(s8, 1, c->eip);
-		else
-			c->src.val = insn_fetch(u8, 1, c->eip);
-		break;
-	case SrcAcc:
-		c->src.type = OP_REG;
-		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->src.ptr = &c->regs[VCPU_REGS_RAX];
-		switch (c->src.bytes) {
-			case 1:
-				c->src.val = *(u8 *)c->src.ptr;
-				break;
-			case 2:
-				c->src.val = *(u16 *)c->src.ptr;
-				break;
-			case 4:
-				c->src.val = *(u32 *)c->src.ptr;
-				break;
-			case 8:
-				c->src.val = *(u64 *)c->src.ptr;
-				break;
-		}
-		break;
-	case SrcOne:
-		c->src.bytes = 1;
-		c->src.val = 1;
-		break;
-	case SrcSI:
-		c->src.type = OP_MEM;
-		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->src.ptr = (unsigned long *)
-			register_address(c,  seg_override_base(ctxt, ops, c),
-					 c->regs[VCPU_REGS_RSI]);
-		c->src.val = 0;
-		break;
-	case SrcImmFAddr:
-		c->src.type = OP_IMM;
-		c->src.ptr = (unsigned long *)c->eip;
-		c->src.bytes = c->op_bytes + 2;
-		insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip);
-		break;
-	case SrcMemFAddr:
-		c->src.type = OP_MEM;
-		c->src.ptr = (unsigned long *)c->modrm_ea;
-		c->src.bytes = c->op_bytes + 2;
-		break;
-	}
-
-	/*
-	 * Decode and fetch the second source operand: register, memory
-	 * or immediate.
-	 */
-	switch (c->d & Src2Mask) {
-	case Src2None:
-		break;
-	case Src2CL:
-		c->src2.bytes = 1;
-		c->src2.val = c->regs[VCPU_REGS_RCX] & 0x8;
-		break;
-	case Src2ImmByte:
-		c->src2.type = OP_IMM;
-		c->src2.ptr = (unsigned long *)c->eip;
-		c->src2.bytes = 1;
-		c->src2.val = insn_fetch(u8, 1, c->eip);
-		break;
-	case Src2One:
-		c->src2.bytes = 1;
-		c->src2.val = 1;
-		break;
-	}
-
-	/* Decode and fetch the destination operand: register or memory. */
-	switch (c->d & DstMask) {
-	case ImplicitOps:
-		/* Special instructions do their own operand decoding. */
-		return 0;
-	case DstReg:
-		decode_register_operand(&c->dst, c,
-			 c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
-		break;
-	case DstMem:
-	case DstMem64:
-		if ((c->d & ModRM) && c->modrm_mod == 3) {
-			c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-			c->dst.type = OP_REG;
-			c->dst.val = c->dst.orig_val = c->modrm_val;
-			c->dst.ptr = c->modrm_ptr;
-			break;
-		}
-		c->dst.type = OP_MEM;
-		c->dst.ptr = (unsigned long *)c->modrm_ea;
-		if ((c->d & DstMask) == DstMem64)
-			c->dst.bytes = 8;
-		else
-			c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.val = 0;
-		if (c->d & BitOp) {
-			unsigned long mask = ~(c->dst.bytes * 8 - 1);
-
-			c->dst.ptr = (void *)c->dst.ptr +
-						   (c->src.val & mask) / 8;
-		}
-		break;
-	case DstAcc:
-		c->dst.type = OP_REG;
-		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.ptr = &c->regs[VCPU_REGS_RAX];
-		switch (c->dst.bytes) {
-			case 1:
-				c->dst.val = *(u8 *)c->dst.ptr;
-				break;
-			case 2:
-				c->dst.val = *(u16 *)c->dst.ptr;
-				break;
-			case 4:
-				c->dst.val = *(u32 *)c->dst.ptr;
-				break;
-			case 8:
-				c->dst.val = *(u64 *)c->dst.ptr;
-				break;
-		}
-		c->dst.orig_val = c->dst.val;
-		break;
-	case DstDI:
-		c->dst.type = OP_MEM;
-		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.ptr = (unsigned long *)
-			register_address(c, es_base(ctxt, ops),
-					 c->regs[VCPU_REGS_RDI]);
-		c->dst.val = 0;
-		break;
-	}
-
-done:
-	return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
-}
-
 static int read_emulated(struct x86_emulate_ctxt *ctxt,
 			 struct x86_emulate_ops *ops,
 			 unsigned long addr, void *dest, unsigned size)
@@ -2551,6 +2179,378 @@ static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base,
 }
 
 int
+x86_decode_insn(struct x86_emulate_ctxt *ctxt)
+{
+	struct x86_emulate_ops *ops = ctxt->ops;
+	struct decode_cache *c = &ctxt->decode;
+	int rc = X86EMUL_CONTINUE;
+	int mode = ctxt->mode;
+	int def_op_bytes, def_ad_bytes, dual, goffset;
+	struct opcode opcode, *g_mod012, *g_mod3;
+
+	/* we cannot decode insn before we complete previous rep insn */
+	WARN_ON(ctxt->restart);
+
+	c->eip = ctxt->eip;
+	c->fetch.start = c->fetch.end = c->eip;
+	ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS);
+
+	switch (mode) {
+	case X86EMUL_MODE_REAL:
+	case X86EMUL_MODE_VM86:
+	case X86EMUL_MODE_PROT16:
+		def_op_bytes = def_ad_bytes = 2;
+		break;
+	case X86EMUL_MODE_PROT32:
+		def_op_bytes = def_ad_bytes = 4;
+		break;
+#ifdef CONFIG_X86_64
+	case X86EMUL_MODE_PROT64:
+		def_op_bytes = 4;
+		def_ad_bytes = 8;
+		break;
+#endif
+	default:
+		return -1;
+	}
+
+	c->op_bytes = def_op_bytes;
+	c->ad_bytes = def_ad_bytes;
+
+	/* Legacy prefixes. */
+	for (;;) {
+		switch (c->b = insn_fetch(u8, 1, c->eip)) {
+		case 0x66:	/* operand-size override */
+			/* switch between 2/4 bytes */
+			c->op_bytes = def_op_bytes ^ 6;
+			break;
+		case 0x67:	/* address-size override */
+			if (mode == X86EMUL_MODE_PROT64)
+				/* switch between 4/8 bytes */
+				c->ad_bytes = def_ad_bytes ^ 12;
+			else
+				/* switch between 2/4 bytes */
+				c->ad_bytes = def_ad_bytes ^ 6;
+			break;
+		case 0x26:	/* ES override */
+		case 0x2e:	/* CS override */
+		case 0x36:	/* SS override */
+		case 0x3e:	/* DS override */
+			set_seg_override(c, (c->b >> 3) & 3);
+			break;
+		case 0x64:	/* FS override */
+		case 0x65:	/* GS override */
+			set_seg_override(c, c->b & 7);
+			break;
+		case 0x40 ... 0x4f: /* REX */
+			if (mode != X86EMUL_MODE_PROT64)
+				goto done_prefixes;
+			c->rex_prefix = c->b;
+			continue;
+		case 0xf0:	/* LOCK */
+			c->lock_prefix = 1;
+			break;
+		case 0xf2:	/* REPNE/REPNZ */
+			c->rep_prefix = REPNE_PREFIX;
+			break;
+		case 0xf3:	/* REP/REPE/REPZ */
+			c->rep_prefix = REPE_PREFIX;
+			break;
+		default:
+			goto done_prefixes;
+		}
+
+		/* Any legacy prefix after a REX prefix nullifies its effect. */
+
+		c->rex_prefix = 0;
+	}
+
+done_prefixes:
+
+	/* REX prefix. */
+	if (c->rex_prefix)
+		if (c->rex_prefix & 8)
+			c->op_bytes = 8;	/* REX.W */
+
+	/* Opcode byte(s). */
+	opcode = opcode_table[c->b];
+	if (opcode.flags == 0) {
+		/* Two-byte opcode? */
+		if (c->b == 0x0f) {
+			c->twobyte = 1;
+			c->b = insn_fetch(u8, 1, c->eip);
+			opcode = twobyte_table[c->b];
+		}
+	}
+	c->d = opcode.flags;
+
+	if (c->d & Group) {
+		dual = c->d & GroupDual;
+		c->modrm = insn_fetch(u8, 1, c->eip);
+		--c->eip;
+
+		if (c->d & GroupDual) {
+			g_mod012 = opcode.u.gdual->mod012;
+			g_mod3 = opcode.u.gdual->mod3;
+		} else
+			g_mod012 = g_mod3 = opcode.u.group;
+
+		c->d &= ~(Group | GroupDual);
+
+		goffset = (c->modrm >> 3) & 7;
+
+		if ((c->modrm >> 6) == 3)
+			opcode = g_mod3[goffset];
+		else
+			opcode = g_mod012[goffset];
+		c->d |= opcode.flags;
+	}
+
+	c->execute = opcode.u.execute;
+
+	/* Unrecognised? */
+	if (c->d == 0 || (c->d & Undefined)) {
+		DPRINTF("Cannot emulate %02x\n", c->b);
+		return -1;
+	}
+
+	if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
+		c->op_bytes = 8;
+
+	/* ModRM and SIB bytes. */
+	if (c->d & ModRM)
+		rc = decode_modrm(ctxt, ops);
+	else if (c->d & MemAbs)
+		rc = decode_abs(ctxt, ops);
+	if (rc != X86EMUL_CONTINUE)
+		goto done;
+
+	if (!c->has_seg_override)
+		set_seg_override(c, VCPU_SREG_DS);
+
+	if (!(!c->twobyte && c->b == 0x8d))
+		c->modrm_ea += seg_override_base(ctxt, ops, c);
+
+	if (c->ad_bytes != 8)
+		c->modrm_ea = (u32)c->modrm_ea;
+
+	if (c->rip_relative)
+		c->modrm_ea += c->eip;
+
+	/*
+	 * Decode and fetch the source operand: register, memory
+	 * or immediate.
+	 */
+	switch (c->d & SrcMask) {
+	case SrcNone:
+		break;
+	case SrcReg:
+		decode_register_operand(&c->src, c, 0);
+		break;
+	case SrcMem16:
+		c->src.bytes = 2;
+		goto srcmem_common;
+	case SrcMem32:
+		c->src.bytes = 4;
+		goto srcmem_common;
+	case SrcMem:
+		c->src.bytes = (c->d & ByteOp) ? 1 :
+							   c->op_bytes;
+		/* Don't fetch the address for invlpg: it could be unmapped. */
+		if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7)
+			break;
+	srcmem_common:
+		/*
+		 * For instructions with a ModR/M byte, switch to register
+		 * access if Mod = 3.
+		 */
+		if ((c->d & ModRM) && c->modrm_mod == 3) {
+			c->src.type = OP_REG;
+			c->src.val = c->modrm_val;
+			c->src.ptr = c->modrm_ptr;
+			break;
+		}
+		c->src.type = OP_MEM;
+		c->src.ptr = (unsigned long *)c->modrm_ea;
+		c->src.val = 0;
+		break;
+	case SrcImm:
+	case SrcImmU:
+		c->src.type = OP_IMM;
+		c->src.ptr = (unsigned long *)c->eip;
+		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		if (c->src.bytes == 8)
+			c->src.bytes = 4;
+		/* NB. Immediates are sign-extended as necessary. */
+		switch (c->src.bytes) {
+		case 1:
+			c->src.val = insn_fetch(s8, 1, c->eip);
+			break;
+		case 2:
+			c->src.val = insn_fetch(s16, 2, c->eip);
+			break;
+		case 4:
+			c->src.val = insn_fetch(s32, 4, c->eip);
+			break;
+		}
+		if ((c->d & SrcMask) == SrcImmU) {
+			switch (c->src.bytes) {
+			case 1:
+				c->src.val &= 0xff;
+				break;
+			case 2:
+				c->src.val &= 0xffff;
+				break;
+			case 4:
+				c->src.val &= 0xffffffff;
+				break;
+			}
+		}
+		break;
+	case SrcImmByte:
+	case SrcImmUByte:
+		c->src.type = OP_IMM;
+		c->src.ptr = (unsigned long *)c->eip;
+		c->src.bytes = 1;
+		if ((c->d & SrcMask) == SrcImmByte)
+			c->src.val = insn_fetch(s8, 1, c->eip);
+		else
+			c->src.val = insn_fetch(u8, 1, c->eip);
+		break;
+	case SrcAcc:
+		c->src.type = OP_REG;
+		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->src.ptr = &c->regs[VCPU_REGS_RAX];
+		switch (c->src.bytes) {
+			case 1:
+				c->src.val = *(u8 *)c->src.ptr;
+				break;
+			case 2:
+				c->src.val = *(u16 *)c->src.ptr;
+				break;
+			case 4:
+				c->src.val = *(u32 *)c->src.ptr;
+				break;
+			case 8:
+				c->src.val = *(u64 *)c->src.ptr;
+				break;
+		}
+		break;
+	case SrcOne:
+		c->src.bytes = 1;
+		c->src.val = 1;
+		break;
+	case SrcSI:
+		c->src.type = OP_MEM;
+		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->src.ptr = (unsigned long *)
+			register_address(c,  seg_override_base(ctxt, ops, c),
+					 c->regs[VCPU_REGS_RSI]);
+		c->src.val = 0;
+		break;
+	case SrcImmFAddr:
+		c->src.type = OP_IMM;
+		c->src.ptr = (unsigned long *)c->eip;
+		c->src.bytes = c->op_bytes + 2;
+		insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip);
+		break;
+	case SrcMemFAddr:
+		c->src.type = OP_MEM;
+		c->src.ptr = (unsigned long *)c->modrm_ea;
+		c->src.bytes = c->op_bytes + 2;
+		break;
+	}
+
+	/*
+	 * Decode and fetch the second source operand: register, memory
+	 * or immediate.
+	 */
+	switch (c->d & Src2Mask) {
+	case Src2None:
+		break;
+	case Src2CL:
+		c->src2.bytes = 1;
+		c->src2.val = c->regs[VCPU_REGS_RCX] & 0x8;
+		break;
+	case Src2ImmByte:
+		c->src2.type = OP_IMM;
+		c->src2.ptr = (unsigned long *)c->eip;
+		c->src2.bytes = 1;
+		c->src2.val = insn_fetch(u8, 1, c->eip);
+		break;
+	case Src2One:
+		c->src2.bytes = 1;
+		c->src2.val = 1;
+		break;
+	}
+
+	/* Decode and fetch the destination operand: register or memory. */
+	switch (c->d & DstMask) {
+	case ImplicitOps:
+		/* Special instructions do their own operand decoding. */
+		return 0;
+	case DstReg:
+		decode_register_operand(&c->dst, c,
+			 c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
+		break;
+	case DstMem:
+	case DstMem64:
+		if ((c->d & ModRM) && c->modrm_mod == 3) {
+			c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+			c->dst.type = OP_REG;
+			c->dst.val = c->dst.orig_val = c->modrm_val;
+			c->dst.ptr = c->modrm_ptr;
+			break;
+		}
+		c->dst.type = OP_MEM;
+		c->dst.ptr = (unsigned long *)c->modrm_ea;
+		if ((c->d & DstMask) == DstMem64)
+			c->dst.bytes = 8;
+		else
+			c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->dst.val = 0;
+		if (c->d & BitOp) {
+			unsigned long mask = ~(c->dst.bytes * 8 - 1);
+
+			c->dst.ptr = (void *)c->dst.ptr +
+						   (c->src.val & mask) / 8;
+		}
+		break;
+	case DstAcc:
+		c->dst.type = OP_REG;
+		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->dst.ptr = &c->regs[VCPU_REGS_RAX];
+		switch (c->dst.bytes) {
+			case 1:
+				c->dst.val = *(u8 *)c->dst.ptr;
+				break;
+			case 2:
+				c->dst.val = *(u16 *)c->dst.ptr;
+				break;
+			case 4:
+				c->dst.val = *(u32 *)c->dst.ptr;
+				break;
+			case 8:
+				c->dst.val = *(u64 *)c->dst.ptr;
+				break;
+		}
+		c->dst.orig_val = c->dst.val;
+		break;
+	case DstDI:
+		c->dst.type = OP_MEM;
+		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->dst.ptr = (unsigned long *)
+			register_address(c, es_base(ctxt, ops),
+					 c->regs[VCPU_REGS_RDI]);
+		c->dst.val = 0;
+		break;
+	}
+
+done:
+	return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
+}
+
+int
 x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 {
 	struct x86_emulate_ops *ops = ctxt->ops;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 20/22] KVM: x86 emulator: move decode tables downwards
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (18 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 19/22] KVM: x86 emulator: move x86_decode_insn() downwards Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 21/22] KVM: x86 emulator: allow repeat macro arguments to contain commas Avi Kivity
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

So they can reference execution functions.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |  472 ++++++++++++++++++++++++------------------------
 1 files changed, 236 insertions(+), 236 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 620525f..11fd2c9 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -117,242 +117,6 @@ struct group_dual {
 	struct opcode mod3[8];
 };
 
-#define D(_y) { .flags = (_y) }
-#define N    D(0)
-#define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
-#define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
-#define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
-
-static struct opcode group1[] = {
-	X7(D(Lock)), N
-};
-
-static struct opcode group1A[] = {
-	D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N,
-};
-
-static struct opcode group3[] = {
-	D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM),
-	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
-	X4(D(Undefined)),
-};
-
-static struct opcode group4[] = {
-	D(ByteOp | DstMem | SrcNone | ModRM | Lock), D(ByteOp | DstMem | SrcNone | ModRM | Lock),
-	N, N, N, N, N, N,
-};
-
-static struct opcode group5[] = {
-	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
-	D(SrcMem | ModRM | Stack), N,
-	D(SrcMem | ModRM | Stack), D(SrcMemFAddr | ModRM | ImplicitOps),
-	D(SrcMem | ModRM | Stack), N,
-};
-
-static struct group_dual group7 = { {
-	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
-	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv), D(SrcMem | ModRM | ByteOp | Priv),
-}, {
-	D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
-	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv), N,
-} };
-
-static struct opcode group8[] = {
-	N, N, N, N,
-	D(DstMem | SrcImmByte | ModRM), D(DstMem | SrcImmByte | ModRM | Lock),
-	D(DstMem | SrcImmByte | ModRM | Lock), D(DstMem | SrcImmByte | ModRM | Lock),
-};
-
-static struct group_dual group9 = { {
-	N, D(DstMem64 | ModRM | Lock), N, N, N, N, N, N,
-}, {
-	N, N, N, N, N, N, N, N,
-} };
-
-static struct opcode opcode_table[256] = {
-	/* 0x00 - 0x07 */
-	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
-	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
-	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
-	/* 0x08 - 0x0F */
-	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
-	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
-	D(ImplicitOps | Stack | No64), N,
-	/* 0x10 - 0x17 */
-	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
-	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
-	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
-	/* 0x18 - 0x1F */
-	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
-	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
-	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
-	/* 0x20 - 0x27 */
-	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
-	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
-	/* 0x28 - 0x2F */
-	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
-	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
-	/* 0x30 - 0x37 */
-	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
-	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
-	/* 0x38 - 0x3F */
-	D(ByteOp | DstMem | SrcReg | ModRM), D(DstMem | SrcReg | ModRM),
-	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
-	N, N,
-	/* 0x40 - 0x4F */
-	X16(D(DstReg)),
-	/* 0x50 - 0x57 */
-	X8(D(SrcReg | Stack)),
-	/* 0x58 - 0x5F */
-	X8(D(DstReg | Stack)),
-	/* 0x60 - 0x67 */
-	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
-	N, D(DstReg | SrcMem32 | ModRM | Mov) /* movsxd (x86/64) */ ,
-	N, N, N, N,
-	/* 0x68 - 0x6F */
-	D(SrcImm | Mov | Stack), N, D(SrcImmByte | Mov | Stack), N,
-	D(DstDI | ByteOp | Mov | String), D(DstDI | Mov | String), /* insb, insw/insd */
-	D(SrcSI | ByteOp | ImplicitOps | String), D(SrcSI | ImplicitOps | String), /* outsb, outsw/outsd */
-	/* 0x70 - 0x7F */
-	X16(D(SrcImmByte)),
-	/* 0x80 - 0x87 */
-	G(ByteOp | DstMem | SrcImm | ModRM | Group, group1),
-	G(DstMem | SrcImm | ModRM | Group, group1),
-	G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1),
-	G(DstMem | SrcImmByte | ModRM | Group, group1),
-	D(ByteOp | DstMem | SrcReg | ModRM), D(DstMem | SrcReg | ModRM),
-	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
-	/* 0x88 - 0x8F */
-	D(ByteOp | DstMem | SrcReg | ModRM | Mov), D(DstMem | SrcReg | ModRM | Mov),
-	D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem | ModRM | Mov),
-	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | DstReg),
-	D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
-	/* 0x90 - 0x97 */
-	D(DstReg), D(DstReg), D(DstReg), D(DstReg),	D(DstReg), D(DstReg), D(DstReg), D(DstReg),
-	/* 0x98 - 0x9F */
-	N, N, D(SrcImmFAddr | No64), N,
-	D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
-	/* 0xA0 - 0xA7 */
-	D(ByteOp | DstAcc | SrcMem | Mov | MemAbs), D(DstAcc | SrcMem | Mov | MemAbs),
-	D(ByteOp | DstMem | SrcAcc | Mov | MemAbs), D(DstMem | SrcAcc | Mov | MemAbs),
-	D(ByteOp | SrcSI | DstDI | Mov | String), D(SrcSI | DstDI | Mov | String),
-	D(ByteOp | SrcSI | DstDI | String), D(SrcSI | DstDI | String),
-	/* 0xA8 - 0xAF */
-	D(DstAcc | SrcImmByte | ByteOp), D(DstAcc | SrcImm), D(ByteOp | DstDI | Mov | String), D(DstDI | Mov | String),
-	D(ByteOp | SrcSI | DstAcc | Mov | String), D(SrcSI | DstAcc | Mov | String),
-	D(ByteOp | DstDI | String), D(DstDI | String),
-	/* 0xB0 - 0xB7 */
-	X8(D(ByteOp | DstReg | SrcImm | Mov)),
-	/* 0xB8 - 0xBF */
-	X8(D(DstReg | SrcImm | Mov)),
-	/* 0xC0 - 0xC7 */
-	D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM),
-	N, D(ImplicitOps | Stack), N, N,
-	D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov),
-	/* 0xC8 - 0xCF */
-	N, N, N, D(ImplicitOps | Stack),
-	D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps),
-	/* 0xD0 - 0xD7 */
-	D(ByteOp | DstMem | SrcImplicit | ModRM), D(DstMem | SrcImplicit | ModRM),
-	D(ByteOp | DstMem | SrcImplicit | ModRM), D(DstMem | SrcImplicit | ModRM),
-	N, N, N, N,
-	/* 0xD8 - 0xDF */
-	N, N, N, N, N, N, N, N,
-	/* 0xE0 - 0xE7 */
-	N, N, N, N,
-	D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc),
-	D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc),
-	/* 0xE8 - 0xEF */
-	D(SrcImm | Stack), D(SrcImm | ImplicitOps),
-	D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps),
-	D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc),
-	D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc),
-	/* 0xF0 - 0xF7 */
-	N, N, N, N,
-	D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3),
-	/* 0xF8 - 0xFF */
-	D(ImplicitOps), N, D(ImplicitOps), D(ImplicitOps),
-	D(ImplicitOps), D(ImplicitOps), G(0, group4), G(0, group5),
-};
-
-static struct opcode twobyte_table[256] = {
-	/* 0x00 - 0x0F */
-	N, GD(0, &group7), N, N,
-	N, D(ImplicitOps), D(ImplicitOps | Priv), N,
-	D(ImplicitOps | Priv), D(ImplicitOps | Priv), N, N,
-	N, D(ImplicitOps | ModRM), N, N,
-	/* 0x10 - 0x1F */
-	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
-	/* 0x20 - 0x2F */
-	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
-	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
-	N, N, N, N,
-	N, N, N, N, N, N, N, N,
-	/* 0x30 - 0x3F */
-	D(ImplicitOps | Priv), N, D(ImplicitOps | Priv), N,
-	D(ImplicitOps), D(ImplicitOps | Priv), N, N,
-	N, N, N, N, N, N, N, N,
-	/* 0x40 - 0x4F */
-	X16(D(DstReg | SrcMem | ModRM | Mov)),
-	/* 0x50 - 0x5F */
-	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
-	/* 0x60 - 0x6F */
-	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
-	/* 0x70 - 0x7F */
-	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
-	/* 0x80 - 0x8F */
-	X16(D(SrcImm)),
-	/* 0x90 - 0x9F */
-	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
-	/* 0xA0 - 0xA7 */
-	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
-	N, D(DstMem | SrcReg | ModRM | BitOp),
-	D(DstMem | SrcReg | Src2ImmByte | ModRM),
-	D(DstMem | SrcReg | Src2CL | ModRM), N, N,
-	/* 0xA8 - 0xAF */
-	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
-	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
-	D(DstMem | SrcReg | Src2ImmByte | ModRM),
-	D(DstMem | SrcReg | Src2CL | ModRM),
-	D(ModRM), N,
-	/* 0xB0 - 0xB7 */
-	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
-	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
-	N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov),
-	    D(DstReg | SrcMem16 | ModRM | Mov),
-	/* 0xB8 - 0xBF */
-	N, N,
-	G(0, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock),
-	N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov),
-	    D(DstReg | SrcMem16 | ModRM | Mov),
-	/* 0xC0 - 0xCF */
-	N, N, N, D(DstMem | SrcReg | ModRM | Mov),
-	N, N, N, GD(0, &group9),
-	N, N, N, N, N, N, N, N,
-	/* 0xD0 - 0xDF */
-	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
-	/* 0xE0 - 0xEF */
-	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
-	/* 0xF0 - 0xFF */
-	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N
-};
-
-#undef D
-#undef N
-#undef G
-#undef GD
-#undef I
-
 /* EFLAGS bit definitions. */
 #define EFLG_ID (1<<21)
 #define EFLG_VIP (1<<20)
@@ -2178,6 +1942,242 @@ static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base,
 	op->ptr = (unsigned long *)register_address(c,  base, c->regs[reg]);
 }
 
+#define D(_y) { .flags = (_y) }
+#define N    D(0)
+#define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
+#define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
+#define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
+
+static struct opcode group1[] = {
+	X7(D(Lock)), N
+};
+
+static struct opcode group1A[] = {
+	D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N,
+};
+
+static struct opcode group3[] = {
+	D(DstMem | SrcImm | ModRM), D(DstMem | SrcImm | ModRM),
+	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
+	X4(D(Undefined)),
+};
+
+static struct opcode group4[] = {
+	D(ByteOp | DstMem | SrcNone | ModRM | Lock), D(ByteOp | DstMem | SrcNone | ModRM | Lock),
+	N, N, N, N, N, N,
+};
+
+static struct opcode group5[] = {
+	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
+	D(SrcMem | ModRM | Stack), N,
+	D(SrcMem | ModRM | Stack), D(SrcMemFAddr | ModRM | ImplicitOps),
+	D(SrcMem | ModRM | Stack), N,
+};
+
+static struct group_dual group7 = { {
+	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
+	D(SrcNone | ModRM | DstMem | Mov), N,
+	D(SrcMem16 | ModRM | Mov | Priv), D(SrcMem | ModRM | ByteOp | Priv),
+}, {
+	D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
+	D(SrcNone | ModRM | DstMem | Mov), N,
+	D(SrcMem16 | ModRM | Mov | Priv), N,
+} };
+
+static struct opcode group8[] = {
+	N, N, N, N,
+	D(DstMem | SrcImmByte | ModRM), D(DstMem | SrcImmByte | ModRM | Lock),
+	D(DstMem | SrcImmByte | ModRM | Lock), D(DstMem | SrcImmByte | ModRM | Lock),
+};
+
+static struct group_dual group9 = { {
+	N, D(DstMem64 | ModRM | Lock), N, N, N, N, N, N,
+}, {
+	N, N, N, N, N, N, N, N,
+} };
+
+static struct opcode opcode_table[256] = {
+	/* 0x00 - 0x07 */
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+	/* 0x08 - 0x0F */
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	D(ImplicitOps | Stack | No64), N,
+	/* 0x10 - 0x17 */
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+	/* 0x18 - 0x1F */
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+	/* 0x20 - 0x27 */
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
+	/* 0x28 - 0x2F */
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
+	/* 0x30 - 0x37 */
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
+	/* 0x38 - 0x3F */
+	D(ByteOp | DstMem | SrcReg | ModRM), D(DstMem | SrcReg | ModRM),
+	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstAcc | SrcImm), D(DstAcc | SrcImm),
+	N, N,
+	/* 0x40 - 0x4F */
+	X16(D(DstReg)),
+	/* 0x50 - 0x57 */
+	X8(D(SrcReg | Stack)),
+	/* 0x58 - 0x5F */
+	X8(D(DstReg | Stack)),
+	/* 0x60 - 0x67 */
+	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+	N, D(DstReg | SrcMem32 | ModRM | Mov) /* movsxd (x86/64) */ ,
+	N, N, N, N,
+	/* 0x68 - 0x6F */
+	D(SrcImm | Mov | Stack), N, D(SrcImmByte | Mov | Stack), N,
+	D(DstDI | ByteOp | Mov | String), D(DstDI | Mov | String), /* insb, insw/insd */
+	D(SrcSI | ByteOp | ImplicitOps | String), D(SrcSI | ImplicitOps | String), /* outsb, outsw/outsd */
+	/* 0x70 - 0x7F */
+	X16(D(SrcImmByte)),
+	/* 0x80 - 0x87 */
+	G(ByteOp | DstMem | SrcImm | ModRM | Group, group1),
+	G(DstMem | SrcImm | ModRM | Group, group1),
+	G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1),
+	G(DstMem | SrcImmByte | ModRM | Group, group1),
+	D(ByteOp | DstMem | SrcReg | ModRM), D(DstMem | SrcReg | ModRM),
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	/* 0x88 - 0x8F */
+	D(ByteOp | DstMem | SrcReg | ModRM | Mov), D(DstMem | SrcReg | ModRM | Mov),
+	D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem | ModRM | Mov),
+	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | DstReg),
+	D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
+	/* 0x90 - 0x97 */
+	D(DstReg), D(DstReg), D(DstReg), D(DstReg),	D(DstReg), D(DstReg), D(DstReg), D(DstReg),
+	/* 0x98 - 0x9F */
+	N, N, D(SrcImmFAddr | No64), N,
+	D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
+	/* 0xA0 - 0xA7 */
+	D(ByteOp | DstAcc | SrcMem | Mov | MemAbs), D(DstAcc | SrcMem | Mov | MemAbs),
+	D(ByteOp | DstMem | SrcAcc | Mov | MemAbs), D(DstMem | SrcAcc | Mov | MemAbs),
+	D(ByteOp | SrcSI | DstDI | Mov | String), D(SrcSI | DstDI | Mov | String),
+	D(ByteOp | SrcSI | DstDI | String), D(SrcSI | DstDI | String),
+	/* 0xA8 - 0xAF */
+	D(DstAcc | SrcImmByte | ByteOp), D(DstAcc | SrcImm), D(ByteOp | DstDI | Mov | String), D(DstDI | Mov | String),
+	D(ByteOp | SrcSI | DstAcc | Mov | String), D(SrcSI | DstAcc | Mov | String),
+	D(ByteOp | DstDI | String), D(DstDI | String),
+	/* 0xB0 - 0xB7 */
+	X8(D(ByteOp | DstReg | SrcImm | Mov)),
+	/* 0xB8 - 0xBF */
+	X8(D(DstReg | SrcImm | Mov)),
+	/* 0xC0 - 0xC7 */
+	D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM),
+	N, D(ImplicitOps | Stack), N, N,
+	D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov),
+	/* 0xC8 - 0xCF */
+	N, N, N, D(ImplicitOps | Stack),
+	D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps),
+	/* 0xD0 - 0xD7 */
+	D(ByteOp | DstMem | SrcImplicit | ModRM), D(DstMem | SrcImplicit | ModRM),
+	D(ByteOp | DstMem | SrcImplicit | ModRM), D(DstMem | SrcImplicit | ModRM),
+	N, N, N, N,
+	/* 0xD8 - 0xDF */
+	N, N, N, N, N, N, N, N,
+	/* 0xE0 - 0xE7 */
+	N, N, N, N,
+	D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc),
+	D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc),
+	/* 0xE8 - 0xEF */
+	D(SrcImm | Stack), D(SrcImm | ImplicitOps),
+	D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps),
+	D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc),
+	D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc),
+	/* 0xF0 - 0xF7 */
+	N, N, N, N,
+	D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3),
+	/* 0xF8 - 0xFF */
+	D(ImplicitOps), N, D(ImplicitOps), D(ImplicitOps),
+	D(ImplicitOps), D(ImplicitOps), G(0, group4), G(0, group5),
+};
+
+static struct opcode twobyte_table[256] = {
+	/* 0x00 - 0x0F */
+	N, GD(0, &group7), N, N,
+	N, D(ImplicitOps), D(ImplicitOps | Priv), N,
+	D(ImplicitOps | Priv), D(ImplicitOps | Priv), N, N,
+	N, D(ImplicitOps | ModRM), N, N,
+	/* 0x10 - 0x1F */
+	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
+	/* 0x20 - 0x2F */
+	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
+	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
+	N, N, N, N,
+	N, N, N, N, N, N, N, N,
+	/* 0x30 - 0x3F */
+	D(ImplicitOps | Priv), N, D(ImplicitOps | Priv), N,
+	D(ImplicitOps), D(ImplicitOps | Priv), N, N,
+	N, N, N, N, N, N, N, N,
+	/* 0x40 - 0x4F */
+	X16(D(DstReg | SrcMem | ModRM | Mov)),
+	/* 0x50 - 0x5F */
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+	/* 0x60 - 0x6F */
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+	/* 0x70 - 0x7F */
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+	/* 0x80 - 0x8F */
+	X16(D(SrcImm)),
+	/* 0x90 - 0x9F */
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+	/* 0xA0 - 0xA7 */
+	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
+	N, D(DstMem | SrcReg | ModRM | BitOp),
+	D(DstMem | SrcReg | Src2ImmByte | ModRM),
+	D(DstMem | SrcReg | Src2CL | ModRM), N, N,
+	/* 0xA8 - 0xAF */
+	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
+	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
+	D(DstMem | SrcReg | Src2ImmByte | ModRM),
+	D(DstMem | SrcReg | Src2CL | ModRM),
+	D(ModRM), N,
+	/* 0xB0 - 0xB7 */
+	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
+	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
+	N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov),
+	    D(DstReg | SrcMem16 | ModRM | Mov),
+	/* 0xB8 - 0xBF */
+	N, N,
+	G(0, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock),
+	N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov),
+	    D(DstReg | SrcMem16 | ModRM | Mov),
+	/* 0xC0 - 0xCF */
+	N, N, N, D(DstMem | SrcReg | ModRM | Mov),
+	N, N, N, GD(0, &group9),
+	N, N, N, N, N, N, N, N,
+	/* 0xD0 - 0xDF */
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+	/* 0xE0 - 0xEF */
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+	/* 0xF0 - 0xFF */
+	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N
+};
+
+#undef D
+#undef N
+#undef G
+#undef GD
+#undef I
+
 int
 x86_decode_insn(struct x86_emulate_ctxt *ctxt)
 {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 21/22] KVM: x86 emulator: allow repeat macro arguments to contain commas
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (19 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 20/22] KVM: x86 emulator: move decode tables downwards Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-29 12:11 ` [PATCH 22/22] KVM: x86 emulator: convert some push instructions to direct decode Avi Kivity
  2010-07-31  1:58 ` [PATCH 00/22] Direct decode in emulator Marcelo Tosatti
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Needed for repeating instructions with execution functions.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 11fd2c9..3b8a316 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -94,14 +94,14 @@
 #define Src2One     (3<<29)
 #define Src2Mask    (7<<29)
 
-#define X2(x) x, x
-#define X3(x) X2(x), x
-#define X4(x) X2(x), X2(x)
-#define X5(x) X4(x), x
-#define X6(x) X4(x), X2(x)
-#define X7(x) X4(x), X3(x)
-#define X8(x) X4(x), X4(x)
-#define X16(x) X8(x), X8(x)
+#define X2(x...) x, x
+#define X3(x...) X2(x), x
+#define X4(x...) X2(x), X2(x)
+#define X5(x...) X4(x), x
+#define X6(x...) X4(x), X2(x)
+#define X7(x...) X4(x), X3(x)
+#define X8(x...) X4(x), X4(x)
+#define X16(x...) X8(x), X8(x)
 
 struct opcode {
 	u32 flags;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 22/22] KVM: x86 emulator: convert some push instructions to direct decode
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (20 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 21/22] KVM: x86 emulator: allow repeat macro arguments to contain commas Avi Kivity
@ 2010-07-29 12:11 ` Avi Kivity
  2010-07-31  1:58 ` [PATCH 00/22] Direct decode in emulator Marcelo Tosatti
  22 siblings, 0 replies; 24+ messages in thread
From: Avi Kivity @ 2010-07-29 12:11 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 3b8a316..fedfc9c 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1942,6 +1942,12 @@ static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base,
 	op->ptr = (unsigned long *)register_address(c,  base, c->regs[reg]);
 }
 
+static int em_push(struct x86_emulate_ctxt *ctxt)
+{
+	emulate_push(ctxt, ctxt->ops);
+	return X86EMUL_CONTINUE;
+}
+
 #define D(_y) { .flags = (_y) }
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
@@ -2037,7 +2043,7 @@ static struct opcode opcode_table[256] = {
 	/* 0x40 - 0x4F */
 	X16(D(DstReg)),
 	/* 0x50 - 0x57 */
-	X8(D(SrcReg | Stack)),
+	X8(I(SrcReg | Stack, em_push)),
 	/* 0x58 - 0x5F */
 	X8(D(DstReg | Stack)),
 	/* 0x60 - 0x67 */
@@ -2045,7 +2051,8 @@ static struct opcode opcode_table[256] = {
 	N, D(DstReg | SrcMem32 | ModRM | Mov) /* movsxd (x86/64) */ ,
 	N, N, N, N,
 	/* 0x68 - 0x6F */
-	D(SrcImm | Mov | Stack), N, D(SrcImmByte | Mov | Stack), N,
+	I(SrcImm | Mov | Stack, em_push), N,
+	I(SrcImmByte | Mov | Stack, em_push), N,
 	D(DstDI | ByteOp | Mov | String), D(DstDI | Mov | String), /* insb, insw/insd */
 	D(SrcSI | ByteOp | ImplicitOps | String), D(SrcSI | ImplicitOps | String), /* outsb, outsw/outsd */
 	/* 0x70 - 0x7F */
@@ -2712,9 +2719,6 @@ special_insn:
 	case 0x48 ... 0x4f: /* dec r16/r32 */
 		emulate_1op("dec", c->dst, ctxt->eflags);
 		break;
-	case 0x50 ... 0x57:  /* push reg */
-		emulate_push(ctxt, ops);
-		break;
 	case 0x58 ... 0x5f: /* pop reg */
 	pop_instruction:
 		rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
@@ -2736,10 +2740,6 @@ special_insn:
 			goto cannot_emulate;
 		c->dst.val = (s32) c->src.val;
 		break;
-	case 0x68: /* push imm */
-	case 0x6a: /* push imm8 */
-		emulate_push(ctxt, ops);
-		break;
 	case 0x6c:		/* insb */
 	case 0x6d:		/* insw/insd */
 		c->dst.bytes = min(c->dst.bytes, 4u);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 00/22] Direct decode in emulator
  2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
                   ` (21 preceding siblings ...)
  2010-07-29 12:11 ` [PATCH 22/22] KVM: x86 emulator: convert some push instructions to direct decode Avi Kivity
@ 2010-07-31  1:58 ` Marcelo Tosatti
  22 siblings, 0 replies; 24+ messages in thread
From: Marcelo Tosatti @ 2010-07-31  1:58 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm

On Thu, Jul 29, 2010 at 03:11:33PM +0300, Avi Kivity wrote:
> Currently the emulator decoder is indirect in two ways: groups are looked up
> in a separate table based on group number; and opcode execution is looked up
> in a big switch (actually two) after the opcode flags lookup.
> 
> This patchset converts groups to direct decode and begins the work for opcode
> decode.
> 
> The motivations are:
> - reduce errors from discrepancies between the two tables (like we had for
>   IRET)
> - make the code easier to read, removing many switch () statements
> - eventually remove the #UD mini-decoder in x86.c by adding subgroup support
>   to the emulator
> 
> Avi Kivity (22):
>   KVM: x86 emulator: drop parentheses in repreat macros
>   KVM: x86 emulator: introduce 'struct opcode'
>   KVM: x86 emulator: Add wrappers for easily defining opcodes
>   KVM: x86 emulator: move group tables to top
>   KVM: x86 emulator: reserve group code 0
>   KVM: x86 emulator: allow specifying group directly in opcode
>   KVM: x86 emulator: convert group 1 to new style
>   KVM: x86 emulator: convert group 1A to new style
>   KVM: x86 emulator: convert group 3 to new style
>   KVM: x86 emulator: convert group 4 to new style
>   KVM: x86 emulator: convert group 5 to new style
>   KVM: x86 emulator: convert group 7 to new style
>   KVM: x86 emulator: convert group 8 to new style
>   KVM: x86 emulator: convert group 9 to new style
>   KVM: x86 emulator: drop support for old-style groups
>   KVM: x86 emulator: move ByteOp and Dst back to bits 0:3
>   KVM: x86 emulator: store x86_emulate_ops in emulation context
>   KVM: x86 emulator: allow storing emulator execution function in
>     decode tables
>   KVM: x86 emulator: move x86_decode_insn() downwards
>   KVM: x86 emulator: move decode tables downwards
>   KVM: x86 emulator: allow repeat macro arguments to contain commas
>   KVM: x86 emulator: convert some push instructions to direct decode
> 
>  arch/x86/include/asm/kvm_emulate.h |   10 +-
>  arch/x86/kvm/emulate.c             | 1253 +++++++++++++++++++-----------------
>  arch/x86/kvm/x86.c                 |    7 +-
>  3 files changed, 661 insertions(+), 609 deletions(-)

Applied, thanks.


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2010-07-31  3:26 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-29 12:11 [PATCH 00/22] Direct decode in emulator Avi Kivity
2010-07-29 12:11 ` [PATCH 01/22] KVM: x86 emulator: drop parentheses in repreat macros Avi Kivity
2010-07-29 12:11 ` [PATCH 02/22] KVM: x86 emulator: introduce 'struct opcode' Avi Kivity
2010-07-29 12:11 ` [PATCH 03/22] KVM: x86 emulator: Add wrappers for easily defining opcodes Avi Kivity
2010-07-29 12:11 ` [PATCH 04/22] KVM: x86 emulator: move group tables to top Avi Kivity
2010-07-29 12:11 ` [PATCH 05/22] KVM: x86 emulator: reserve group code 0 Avi Kivity
2010-07-29 12:11 ` [PATCH 06/22] KVM: x86 emulator: allow specifying group directly in opcode Avi Kivity
2010-07-29 12:11 ` [PATCH 07/22] KVM: x86 emulator: convert group 1 to new style Avi Kivity
2010-07-29 12:11 ` [PATCH 08/22] KVM: x86 emulator: convert group 1A " Avi Kivity
2010-07-29 12:11 ` [PATCH 09/22] KVM: x86 emulator: convert group 3 " Avi Kivity
2010-07-29 12:11 ` [PATCH 10/22] KVM: x86 emulator: convert group 4 " Avi Kivity
2010-07-29 12:11 ` [PATCH 11/22] KVM: x86 emulator: convert group 5 " Avi Kivity
2010-07-29 12:11 ` [PATCH 12/22] KVM: x86 emulator: convert group 7 " Avi Kivity
2010-07-29 12:11 ` [PATCH 13/22] KVM: x86 emulator: convert group 8 " Avi Kivity
2010-07-29 12:11 ` [PATCH 14/22] KVM: x86 emulator: convert group 9 " Avi Kivity
2010-07-29 12:11 ` [PATCH 15/22] KVM: x86 emulator: drop support for old-style groups Avi Kivity
2010-07-29 12:11 ` [PATCH 16/22] KVM: x86 emulator: move ByteOp and Dst back to bits 0:3 Avi Kivity
2010-07-29 12:11 ` [PATCH 17/22] KVM: x86 emulator: store x86_emulate_ops in emulation context Avi Kivity
2010-07-29 12:11 ` [PATCH 18/22] KVM: x86 emulator: allow storing emulator execution function in decode tables Avi Kivity
2010-07-29 12:11 ` [PATCH 19/22] KVM: x86 emulator: move x86_decode_insn() downwards Avi Kivity
2010-07-29 12:11 ` [PATCH 20/22] KVM: x86 emulator: move decode tables downwards Avi Kivity
2010-07-29 12:11 ` [PATCH 21/22] KVM: x86 emulator: allow repeat macro arguments to contain commas Avi Kivity
2010-07-29 12:11 ` [PATCH 22/22] KVM: x86 emulator: convert some push instructions to direct decode Avi Kivity
2010-07-31  1:58 ` [PATCH 00/22] Direct decode in emulator Marcelo Tosatti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox