From: Avi Kivity <avi@redhat.com>
To: Marcelo Tosatti <mtosatti@redhat.com>, kvm@vger.kernel.org
Subject: [PATCH 04/14] KVM: x86 emulator: split dst decode to a generic decode_operand()
Date: Tue, 13 Sep 2011 10:45:41 +0300 [thread overview]
Message-ID: <1315899951-2357-5-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1315899951-2357-1-git-send-email-avi@redhat.com>
Instead of decoding each operand using its own code, use a generic
function. Start with the destination operand.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
arch/x86/kvm/emulate.c | 146 ++++++++++++++++++++++++++++-------------------
1 files changed, 87 insertions(+), 59 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 58172fb..6a6aed9 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -29,6 +29,22 @@
#include "tss.h"
/*
+ * Operand types
+ */
+#define OpNone 0
+#define OpImplicit 1 /* No generic decode */
+#define OpReg 2 /* Register */
+#define OpMem 3 /* Memory */
+#define OpAcc 4 /* Accumulator: AL/AX/EAX/RAX */
+#define OpDI 5 /* ES:DI/EDI/RDI */
+#define OpMem64 6 /* Memory, 64-bit */
+#define OpImmUByte 7 /* Zero-extended 8-bit immediate */
+#define OpDX 8 /* DX register */
+
+#define OpBits 4 /* Width of operand field */
+#define OpMask ((1 << OpBits) - 1)
+
+/*
* Opcode effective-address decode tables.
* Note that we only emulate instructions that have at least one memory
* operand (excluding implicit stack references). We assume that stack
@@ -40,15 +56,16 @@
/* Operand sizes: 8-bit operands or specified/overridden size. */
#define ByteOp (1<<0) /* 8-bit operands. */
/* Destination operand type. */
-#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 DstImmUByte (7<<1) /* 8-bit unsigned immediate operand */
-#define DstDX (8<<1) /* Destination is in DX register */
-#define DstMask (0xf<<1)
+#define DstShift 1
+#define ImplicitOps (OpImplicit << DstShift)
+#define DstReg (OpReg << DstShift)
+#define DstMem (OpMem << DstShift)
+#define DstAcc (OpAcc << DstShift)
+#define DstDI (OpDI << DstShift)
+#define DstMem64 (OpMem64 << DstShift)
+#define DstImmUByte (OpImmUByte << DstShift)
+#define DstDX (OpDX << DstShift)
+#define DstMask (OpMask << DstShift)
/* Source operand type. */
#define SrcNone (0<<5) /* No source operand. */
#define SrcReg (1<<5) /* Register operand. */
@@ -3316,6 +3333,66 @@ static int decode_imm(struct x86_emulate_ctxt *ctxt, struct operand *op,
return rc;
}
+static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
+ unsigned d)
+{
+ int rc = X86EMUL_CONTINUE;
+
+ switch (d) {
+ case OpReg:
+ decode_register_operand(ctxt, op,
+ ctxt->twobyte && (ctxt->b == 0xb6 || ctxt->b == 0xb7));
+ break;
+ case OpImmUByte:
+ op->type = OP_IMM;
+ op->addr.mem.ea = ctxt->_eip;
+ op->bytes = 1;
+ op->val = insn_fetch(u8, ctxt);
+ break;
+ case OpMem:
+ case OpMem64:
+ *op = ctxt->memop;
+ ctxt->memopp = op;
+ if (d == OpMem64)
+ op->bytes = 8;
+ else
+ op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
+ if (ctxt->d & BitOp)
+ fetch_bit_operand(ctxt);
+ op->orig_val = op->val;
+ break;
+ case OpAcc:
+ op->type = OP_REG;
+ op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
+ op->addr.reg = &ctxt->regs[VCPU_REGS_RAX];
+ fetch_register_operand(op);
+ op->orig_val = op->val;
+ break;
+ case OpDI:
+ op->type = OP_MEM;
+ op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
+ op->addr.mem.ea =
+ register_address(ctxt, ctxt->regs[VCPU_REGS_RDI]);
+ op->addr.mem.seg = VCPU_SREG_ES;
+ op->val = 0;
+ break;
+ case OpDX:
+ op->type = OP_REG;
+ op->bytes = 2;
+ op->addr.reg = &ctxt->regs[VCPU_REGS_RDX];
+ fetch_register_operand(op);
+ break;
+ case OpImplicit:
+ /* Special instructions do their own operand decoding. */
+ default:
+ op->type = OP_NONE; /* Disable writeback. */
+ break;
+ }
+
+done:
+ return rc;
+}
+
int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
{
int rc = X86EMUL_CONTINUE;
@@ -3602,56 +3679,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
goto done;
/* Decode and fetch the destination operand: register or memory. */
- switch (ctxt->d & DstMask) {
- case DstReg:
- decode_register_operand(ctxt, &ctxt->dst,
- ctxt->twobyte && (ctxt->b == 0xb6 || ctxt->b == 0xb7));
- break;
- case DstImmUByte:
- ctxt->dst.type = OP_IMM;
- ctxt->dst.addr.mem.ea = ctxt->_eip;
- ctxt->dst.bytes = 1;
- ctxt->dst.val = insn_fetch(u8, ctxt);
- break;
- case DstMem:
- case DstMem64:
- ctxt->dst = ctxt->memop;
- ctxt->memopp = &ctxt->dst;
- if ((ctxt->d & DstMask) == DstMem64)
- ctxt->dst.bytes = 8;
- else
- ctxt->dst.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
- if (ctxt->d & BitOp)
- fetch_bit_operand(ctxt);
- ctxt->dst.orig_val = ctxt->dst.val;
- break;
- case DstAcc:
- ctxt->dst.type = OP_REG;
- ctxt->dst.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
- ctxt->dst.addr.reg = &ctxt->regs[VCPU_REGS_RAX];
- fetch_register_operand(&ctxt->dst);
- ctxt->dst.orig_val = ctxt->dst.val;
- break;
- case DstDI:
- ctxt->dst.type = OP_MEM;
- ctxt->dst.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
- ctxt->dst.addr.mem.ea =
- register_address(ctxt, ctxt->regs[VCPU_REGS_RDI]);
- ctxt->dst.addr.mem.seg = VCPU_SREG_ES;
- ctxt->dst.val = 0;
- break;
- case DstDX:
- ctxt->dst.type = OP_REG;
- ctxt->dst.bytes = 2;
- ctxt->dst.addr.reg = &ctxt->regs[VCPU_REGS_RDX];
- fetch_register_operand(&ctxt->dst);
- break;
- case ImplicitOps:
- /* Special instructions do their own operand decoding. */
- default:
- ctxt->dst.type = OP_NONE; /* Disable writeback. */
- break;
- }
+ rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask);
done:
if (ctxt->memopp && ctxt->memopp->type == OP_MEM && ctxt->rip_relative)
--
1.7.6.1
next prev parent reply other threads:[~2011-09-13 7:45 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-13 7:45 [PATCH 00/14] Emulator decode generalization Avi Kivity
2011-09-13 7:45 ` [PATCH 01/14] KVM: x86 emulator: fix Src2CL decode Avi Kivity
2011-09-13 7:45 ` [PATCH 02/14] KVM: x86 emulator: convert group 3 instructions to direct decode Avi Kivity
2011-09-13 7:45 ` [PATCH 03/14] KVM: x86 emulator: move memop, memopp into emulation context Avi Kivity
2011-09-14 10:41 ` Takuya Yoshikawa
2011-09-14 11:37 ` Avi Kivity
2011-09-14 15:21 ` Takuya Yoshikawa
2011-09-14 15:25 ` Avi Kivity
2011-09-13 7:45 ` Avi Kivity [this message]
2011-09-13 7:45 ` [PATCH 05/14] KVM: x86 emulator: expand decode flags to 64 bits Avi Kivity
2011-09-13 7:45 ` [PATCH 06/14] KVM: x86 emulator: switch src2 to generic decode_operand() Avi Kivity
2011-09-13 7:45 ` [PATCH 07/14] KVM: x86 emulator: free up some flag bits near src, dst Avi Kivity
2011-09-13 7:45 ` [PATCH 08/14] KVM: x86 emulator: switch OpImmUByte decode to decode_imm() Avi Kivity
2011-09-13 7:45 ` [PATCH 09/14] KVM: x86 emulator: qualify OpReg inhibit_byte_regs hack Avi Kivity
2011-09-13 7:45 ` [PATCH 10/14] KVM: x86 emulator: switch src decode to decode_operand() Avi Kivity
2011-09-13 7:45 ` [PATCH 11/14] KVM: x86 emulator: simplify OpMem64 decode Avi Kivity
2011-09-13 7:45 ` [PATCH 12/14] KVM: x86 emulator: streamline decode of segment registers Avi Kivity
2011-09-13 7:45 ` [PATCH 13/14] KVM: x86 emulator: switch lds/les/lss/lfs/lgs to direct decode Avi Kivity
2011-09-13 7:45 ` [PATCH 14/14] KVM: x86 emulator: convert push %sreg/pop %sreg " Avi Kivity
2011-09-14 11:12 ` [PATCH 00/14] Emulator decode generalization Marcelo Tosatti
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1315899951-2357-5-git-send-email-avi@redhat.com \
--to=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=mtosatti@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.