diff options
author | Avi Kivity <avi@redhat.com> | 2011-09-13 03:45:47 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-09-25 12:52:54 -0400 |
commit | 0fe591288470aebba4104b17513c9ad5050f9d0d (patch) | |
tree | 85712837f1a5e992a018881a98c3565492800f6e /arch/x86 | |
parent | 5217973ef899ffecdd77743aae3b633994a08cde (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.c | 156 |
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 | ||