Commit 3c118e24 authored by Avi Kivity's avatar Avi Kivity

KVM: x86 emulator: Extract the common code of SrcReg and DstReg

Share the common parts of SrcReg and DstReg decoding.
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent de7d789a
...@@ -520,6 +520,34 @@ static int test_cc(unsigned int condition, unsigned int flags) ...@@ -520,6 +520,34 @@ static int test_cc(unsigned int condition, unsigned int flags)
return (!!rc ^ (condition & 1)); return (!!rc ^ (condition & 1));
} }
static void decode_register_operand(struct operand *op,
struct decode_cache *c,
int highbyte_regs,
int inhibit_bytereg)
{
op->type = OP_REG;
if ((c->d & ByteOp) && !inhibit_bytereg) {
op->ptr = decode_register(c->modrm_reg, c->regs, highbyte_regs);
op->val = *(u8 *)op->ptr;
op->bytes = 1;
} else {
op->ptr = decode_register(c->modrm_reg, c->regs, 0);
op->bytes = c->op_bytes;
switch (op->bytes) {
case 2:
op->val = *(u16 *)op->ptr;
break;
case 4:
op->val = *(u32 *)op->ptr;
break;
case 8:
op->val = *(u64 *) op->ptr;
break;
}
}
op->orig_val = op->val;
}
int 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)
{ {
...@@ -809,31 +837,7 @@ modrm_done: ...@@ -809,31 +837,7 @@ modrm_done:
case SrcNone: case SrcNone:
break; break;
case SrcReg: case SrcReg:
c->src.type = OP_REG; decode_register_operand(&c->src, c, rex_prefix == 0, 0);
if (c->d & ByteOp) {
c->src.ptr =
decode_register(c->modrm_reg, c->regs,
(rex_prefix == 0));
c->src.val = c->src.orig_val = *(u8 *)c->src.ptr;
c->src.bytes = 1;
} else {
c->src.ptr =
decode_register(c->modrm_reg, c->regs, 0);
switch ((c->src.bytes = c->op_bytes)) {
case 2:
c->src.val = c->src.orig_val =
*(u16 *) c->src.ptr;
break;
case 4:
c->src.val = c->src.orig_val =
*(u32 *) c->src.ptr;
break;
case 8:
c->src.val = c->src.orig_val =
*(u64 *) c->src.ptr;
break;
}
}
break; break;
case SrcMem16: case SrcMem16:
c->src.bytes = 2; c->src.bytes = 2;
...@@ -891,30 +895,8 @@ modrm_done: ...@@ -891,30 +895,8 @@ modrm_done:
/* Special instructions do their own operand decoding. */ /* Special instructions do their own operand decoding. */
return 0; return 0;
case DstReg: case DstReg:
c->dst.type = OP_REG; decode_register_operand(&c->dst, c, rex_prefix == 0,
if ((c->d & ByteOp) c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
&& !(c->twobyte &&
(c->b == 0xb6 || c->b == 0xb7))) {
c->dst.ptr =
decode_register(c->modrm_reg, c->regs,
(rex_prefix == 0));
c->dst.val = *(u8 *) c->dst.ptr;
c->dst.bytes = 1;
} else {
c->dst.ptr =
decode_register(c->modrm_reg, c->regs, 0);
switch ((c->dst.bytes = c->op_bytes)) {
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;
}
}
break; break;
case DstMem: case DstMem:
if ((c->d & ModRM) && c->modrm_mod == 3) { if ((c->d & ModRM) && c->modrm_mod == 3) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment