aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-09-13 03:45:47 -0400
committerAvi Kivity <avi@redhat.com>2011-09-25 12:52:54 -0400
commit0fe591288470aebba4104b17513c9ad5050f9d0d (patch)
tree85712837f1a5e992a018881a98c3565492800f6e /arch/x86
parent5217973ef899ffecdd77743aae3b633994a08cde (diff)
KVM: x86 emulator: switch src decode to decode_operand()
Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/emulate.c156
1 files changed, 63 insertions, 93 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 17a8910f28ce..e46809b8f31b 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -44,8 +44,15 @@
44#define OpImmByte 10ull /* 8-bit sign extended immediate */ 44#define OpImmByte 10ull /* 8-bit sign extended immediate */
45#define OpOne 11ull /* Implied 1 */ 45#define OpOne 11ull /* Implied 1 */
46#define OpImm 12ull /* Sign extended immediate */ 46#define OpImm 12ull /* Sign extended immediate */
47 47#define OpMem16 13ull /* Memory operand (16-bit). */
48#define OpBits 4 /* Width of operand field */ 48#define OpMem32 14ull /* Memory operand (32-bit). */
49#define OpImmU 15ull /* Immediate operand, zero extended */
50#define OpSI 16ull /* SI/ESI/RSI */
51#define OpImmFAddr 17ull /* Immediate far address */
52#define OpMemFAddr 18ull /* Far address in memory */
53#define OpImmU16 19ull /* Immediate operand, 16 bits, zero extended */
54
55#define OpBits 5 /* Width of operand field */
49#define OpMask ((1ull << OpBits) - 1) 56#define OpMask ((1ull << OpBits) - 1)
50 57
51/* 58/*
@@ -71,23 +78,24 @@
71#define DstDX (OpDX << DstShift) 78#define DstDX (OpDX << DstShift)
72#define DstMask (OpMask << DstShift) 79#define DstMask (OpMask << DstShift)
73/* Source operand type. */ 80/* Source operand type. */
74#define SrcNone (0<<5) /* No source operand. */ 81#define SrcShift 6
75#define SrcReg (1<<5) /* Register operand. */ 82#define SrcNone (OpNone << SrcShift)
76#define SrcMem (2<<5) /* Memory operand. */ 83#define SrcReg (OpReg << SrcShift)
77#define SrcMem16 (3<<5) /* Memory operand (16-bit). */ 84#define SrcMem (OpMem << SrcShift)
78#define SrcMem32 (4<<5) /* Memory operand (32-bit). */ 85#define SrcMem16 (OpMem16 << SrcShift)
79#define SrcImm (5<<5) /* Immediate operand. */ 86#define SrcMem32 (OpMem32 << SrcShift)
80#define SrcImmByte (6<<5) /* 8-bit sign-extended immediate operand. */ 87#define SrcImm (OpImm << SrcShift)
81#define SrcOne (7<<5) /* Implied '1' */ 88#define SrcImmByte (OpImmByte << SrcShift)
82#define SrcImmUByte (8<<5) /* 8-bit unsigned immediate operand. */ 89#define SrcOne (OpOne << SrcShift)
83#define SrcImmU (9<<5) /* Immediate operand, unsigned */ 90#define SrcImmUByte (OpImmUByte << SrcShift)
84#define SrcSI (0xa<<5) /* Source is in the DS:RSI */ 91#define SrcImmU (OpImmU << SrcShift)
85#define SrcImmFAddr (0xb<<5) /* Source is immediate far address */ 92#define SrcSI (OpSI << SrcShift)
86#define SrcMemFAddr (0xc<<5) /* Source is far address in memory */ 93#define SrcImmFAddr (OpImmFAddr << SrcShift)
87#define SrcAcc (0xd<<5) /* Source Accumulator */ 94#define SrcMemFAddr (OpMemFAddr << SrcShift)
88#define SrcImmU16 (0xe<<5) /* Immediate operand, unsigned, 16 bits */ 95#define SrcAcc (OpAcc << SrcShift)
89#define SrcDX (0xf<<5) /* Source is in DX register */ 96#define SrcImmU16 (OpImmU16 << SrcShift)
90#define SrcMask (0xf<<5) 97#define SrcDX (OpDX << SrcShift)
98#define SrcMask (OpMask << SrcShift)
91#define BitOp (1<<11) 99#define BitOp (1<<11)
92#define MemAbs (1<<12) /* Memory operand is absolute displacement */ 100#define MemAbs (1<<12) /* Memory operand is absolute displacement */
93#define String (1<<13) /* String instruction (rep capable) */ 101#define String (1<<13) /* String instruction (rep capable) */
@@ -3354,13 +3362,14 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
3354 break; 3362 break;
3355 case OpMem: 3363 case OpMem:
3356 case OpMem64: 3364 case OpMem64:
3357 *op = ctxt->memop;
3358 ctxt->memopp = op;
3359 if (d == OpMem64) 3365 if (d == OpMem64)
3360 op->bytes = 8; 3366 ctxt->memop.bytes = 8;
3361 else 3367 else
3362 op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; 3368 ctxt->memop.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
3363 if (ctxt->d & BitOp) 3369 mem_common:
3370 *op = ctxt->memop;
3371 ctxt->memopp = op;
3372 if ((ctxt->d & BitOp) && op == &ctxt->dst)
3364 fetch_bit_operand(ctxt); 3373 fetch_bit_operand(ctxt);
3365 op->orig_val = op->val; 3374 op->orig_val = op->val;
3366 break; 3375 break;
@@ -3399,6 +3408,35 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
3399 case OpImm: 3408 case OpImm:
3400 rc = decode_imm(ctxt, op, imm_size(ctxt), true); 3409 rc = decode_imm(ctxt, op, imm_size(ctxt), true);
3401 break; 3410 break;
3411 case OpMem16:
3412 ctxt->memop.bytes = 2;
3413 goto mem_common;
3414 case OpMem32:
3415 ctxt->memop.bytes = 4;
3416 goto mem_common;
3417 case OpImmU16:
3418 rc = decode_imm(ctxt, op, 2, false);
3419 break;
3420 case OpImmU:
3421 rc = decode_imm(ctxt, op, imm_size(ctxt), false);
3422 break;
3423 case OpSI:
3424 op->type = OP_MEM;
3425 op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
3426 op->addr.mem.ea =
3427 register_address(ctxt, ctxt->regs[VCPU_REGS_RSI]);
3428 op->addr.mem.seg = seg_override(ctxt);
3429 op->val = 0;
3430 break;
3431 case OpImmFAddr:
3432 op->type = OP_IMM;
3433 op->addr.mem.ea = ctxt->_eip;
3434 op->bytes = ctxt->op_bytes + 2;
3435 insn_fetch_arr(op->valptr, op->bytes, ctxt);
3436 break;
3437 case OpMemFAddr:
3438 ctxt->memop.bytes = ctxt->op_bytes + 2;
3439 goto mem_common;
3402 case OpImplicit: 3440 case OpImplicit:
3403 /* Special instructions do their own operand decoding. */ 3441 /* Special instructions do their own operand decoding. */
3404 default: 3442 default:
@@ -3597,75 +3635,7 @@ done_prefixes:
3597 * Decode and fetch the source operand: register, memory 3635 * Decode and fetch the source operand: register, memory
3598 * or immediate. 3636 * or immediate.
3599 */ 3637 */
3600 switch (ctxt->d & SrcMask) { 3638 rc = decode_operand(ctxt, &ctxt->src, (ctxt->d >> SrcShift) & OpMask);
3601 case SrcNone:
3602 break;
3603 case SrcReg:
3604 decode_register_operand(ctxt, &ctxt->src, 0);
3605 break;
3606 case SrcMem16:
3607 ctxt->memop.bytes = 2;
3608 goto srcmem_common;
3609 case SrcMem32:
3610 ctxt->memop.bytes = 4;
3611 goto srcmem_common;
3612 case SrcMem:
3613 ctxt->memop.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
3614 srcmem_common:
3615 ctxt->src = ctxt->memop;
3616 ctxt->memopp = &ctxt->src;
3617 break;
3618 case SrcImmU16:
3619 rc = decode_imm(ctxt, &ctxt->src, 2, false);
3620 break;
3621 case SrcImm:
3622 rc = decode_imm(ctxt, &ctxt->src, imm_size(ctxt), true);
3623 break;
3624 case SrcImmU:
3625 rc = decode_imm(ctxt, &ctxt->src, imm_size(ctxt), false);
3626 break;
3627 case SrcImmByte:
3628 rc = decode_imm(ctxt, &ctxt->src, 1, true);
3629 break;
3630 case SrcImmUByte:
3631 rc = decode_imm(ctxt, &ctxt->src, 1, false);
3632 break;
3633 case SrcAcc:
3634 ctxt->src.type = OP_REG;
3635 ctxt->src.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
3636 ctxt->src.addr.reg = &ctxt->regs[VCPU_REGS_RAX];
3637 fetch_register_operand(&ctxt->src);
3638 break;
3639 case SrcOne:
3640 ctxt->src.bytes = 1;
3641 ctxt->src.val = 1;
3642 break;
3643 case SrcSI:
3644 ctxt->src.type = OP_MEM;
3645 ctxt->src.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
3646 ctxt->src.addr.mem.ea =
3647 register_address(ctxt, ctxt->regs[VCPU_REGS_RSI]);
3648 ctxt->src.addr.mem.seg = seg_override(ctxt);
3649 ctxt->src.val = 0;
3650 break;
3651 case SrcImmFAddr:
3652 ctxt->src.type = OP_IMM;
3653 ctxt->src.addr.mem.ea = ctxt->_eip;
3654 ctxt->src.bytes = ctxt->op_bytes + 2;
3655 insn_fetch_arr(ctxt->src.valptr, ctxt->src.bytes, ctxt);
3656 break;
3657 case SrcMemFAddr:
3658 ctxt->memop.bytes = ctxt->op_bytes + 2;
3659 goto srcmem_common;
3660 break;
3661 case SrcDX:
3662 ctxt->src.type = OP_REG;
3663 ctxt->src.bytes = 2;
3664 ctxt->src.addr.reg = &ctxt->regs[VCPU_REGS_RDX];
3665 fetch_register_operand(&ctxt->src);
3666 break;
3667 }
3668
3669 if (rc != X86EMUL_CONTINUE) 3639 if (rc != X86EMUL_CONTINUE)
3670 goto done; 3640 goto done;
3671 3641