To improve readability, move push, writeback, and grp 1a/2/3/4/5/9 emulation
parts to functions.
Signed-off-by: Laurent Vivier [EMAIL PROTECTED]
---
drivers/kvm/x86_emulate.c | 447 ++---
1 files changed, 262 insertions(+), 185 deletions(-)
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 3a1c712..67fe1e1 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -898,6 +898,240 @@ done:
return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
}
+static inline void emulate_push(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = ctxt-decode;
+
+ c-dst.type = OP_MEM;
+ c-dst.bytes = c-op_bytes;
+ c-dst.val = c-src.val;
+ register_address_increment(c-regs[VCPU_REGS_RSP], -c-op_bytes);
+ c-dst.ptr = (void *) register_address(ctxt-ss_base,
c-regs[VCPU_REGS_RSP]);
+}
+
+static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, struct
x86_emulate_ops *ops)
+{
+ struct decode_cache *c = ctxt-decode;
+ int rc;
+
+ /* 64-bit mode: POP always pops a 64-bit operand. */
+
+ if (ctxt-mode == X86EMUL_MODE_PROT64)
+ c-dst.bytes = 8;
+
+ rc = ops-read_std(register_address(ctxt-ss_base,
c-regs[VCPU_REGS_RSP]),
+ c-dst.val, c-dst.bytes, ctxt-vcpu);
+ if (rc != 0)
+ return rc;
+
+ register_address_increment(c-regs[VCPU_REGS_RSP], c-dst.bytes);
+
+ return 0;
+}
+
+static inline void emulate_grp2(struct decode_cache *c, unsigned long *_eflags)
+{
+ switch (c-modrm_reg) {
+ case 0: /* rol */
+ emulate_2op_SrcB(rol, c-src, c-dst, *_eflags);
+ break;
+ case 1: /* ror */
+ emulate_2op_SrcB(ror, c-src, c-dst, *_eflags);
+ break;
+ case 2: /* rcl */
+ emulate_2op_SrcB(rcl, c-src, c-dst, *_eflags);
+ break;
+ case 3: /* rcr */
+ emulate_2op_SrcB(rcr, c-src, c-dst, *_eflags);
+ break;
+ case 4: /* sal/shl */
+ case 6: /* sal/shl */
+ emulate_2op_SrcB(sal, c-src, c-dst, *_eflags);
+ break;
+ case 5: /* shr */
+ emulate_2op_SrcB(shr, c-src, c-dst, *_eflags);
+ break;
+ case 7: /* sar */
+ emulate_2op_SrcB(sar, c-src, c-dst, *_eflags);
+ break;
+ }
+}
+
+static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops,
+ unsigned long *_eflags)
+{
+ struct decode_cache *c = ctxt-decode;
+ int rc = 0;
+
+ switch (c-modrm_reg) {
+ case 0 ... 1: /* test */
+ /*
+* Special case in Grp3: test has an immediate
+* source operand.
+*/
+ 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;
+ 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;
+ }
+ emulate_2op_SrcV(test, c-src, c-dst, *_eflags);
+ break;
+ case 2: /* not */
+ c-dst.val = ~c-dst.val;
+ break;
+ case 3: /* neg */
+ emulate_1op(neg, c-dst, *_eflags);
+ break;
+ default:
+ DPRINTF(Cannot emulate %02x\n, c-b);
+ rc = X86EMUL_UNHANDLEABLE;
+ break;
+ }
+done:
+ return rc;
+}
+
+static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops,
+ unsigned long *_eflags,
+ int *no_wb)
+{
+ struct decode_cache *c = ctxt-decode;
+ int rc;
+
+ switch (c-modrm_reg) {
+ case 0: /* inc */
+ emulate_1op(inc, c-dst, *_eflags);
+ break;
+ case 1: /* dec */
+ emulate_1op(dec, c-dst, *_eflags);
+ break;
+ case 4: /* jmp abs */
+ if (c-b == 0xff)
+ c-eip = c-dst.val;
+ else {
+ DPRINTF(Cannot emulate %02x\n, c-b);
+ return X86EMUL_UNHANDLEABLE;
+ }
+ break;
+ case 6: /* push */
+
+ /* 64-bit mode: PUSH always pushes a 64-bit operand. */
+
+ if (ctxt-mode == X86EMUL_MODE_PROT64) {
+ c-dst.bytes =