Commit ef65c889 authored by Avi Kivity's avatar Avi Kivity
Browse files

KVM: x86 emulator: allow storing emulator execution function in decode tables



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: default avatarAvi Kivity <avi@redhat.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 9aabc88f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -190,6 +190,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 */
+12 −0
Original line number Diff line number Diff line
@@ -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)
@@ -1070,6 +1073,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);
@@ -2705,6 +2710,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;