2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-27 14:43:58 +08:00

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>
This commit is contained in:
Avi Kivity 2011-09-13 10:45:47 +03:00
parent 5217973ef8
commit 0fe5912884

View File

@ -44,8 +44,15 @@
#define OpImmByte 10ull /* 8-bit sign extended immediate */ #define OpImmByte 10ull /* 8-bit sign extended immediate */
#define OpOne 11ull /* Implied 1 */ #define OpOne 11ull /* Implied 1 */
#define OpImm 12ull /* Sign extended immediate */ #define OpImm 12ull /* Sign extended immediate */
#define OpMem16 13ull /* Memory operand (16-bit). */
#define OpMem32 14ull /* Memory operand (32-bit). */
#define OpImmU 15ull /* Immediate operand, zero extended */
#define OpSI 16ull /* SI/ESI/RSI */
#define OpImmFAddr 17ull /* Immediate far address */
#define OpMemFAddr 18ull /* Far address in memory */
#define OpImmU16 19ull /* Immediate operand, 16 bits, zero extended */
#define OpBits 4 /* Width of operand field */ #define OpBits 5 /* Width of operand field */
#define OpMask ((1ull << OpBits) - 1) #define OpMask ((1ull << OpBits) - 1)
/* /*
@ -71,23 +78,24 @@
#define DstDX (OpDX << DstShift) #define DstDX (OpDX << DstShift)
#define DstMask (OpMask << DstShift) #define DstMask (OpMask << DstShift)
/* Source operand type. */ /* Source operand type. */
#define SrcNone (0<<5) /* No source operand. */ #define SrcShift 6
#define SrcReg (1<<5) /* Register operand. */ #define SrcNone (OpNone << SrcShift)
#define SrcMem (2<<5) /* Memory operand. */ #define SrcReg (OpReg << SrcShift)
#define SrcMem16 (3<<5) /* Memory operand (16-bit). */ #define SrcMem (OpMem << SrcShift)
#define SrcMem32 (4<<5) /* Memory operand (32-bit). */ #define SrcMem16 (OpMem16 << SrcShift)
#define SrcImm (5<<5) /* Immediate operand. */ #define SrcMem32 (OpMem32 << SrcShift)
#define SrcImmByte (6<<5) /* 8-bit sign-extended immediate operand. */ #define SrcImm (OpImm << SrcShift)
#define SrcOne (7<<5) /* Implied '1' */ #define SrcImmByte (OpImmByte << SrcShift)
#define SrcImmUByte (8<<5) /* 8-bit unsigned immediate operand. */ #define SrcOne (OpOne << SrcShift)
#define SrcImmU (9<<5) /* Immediate operand, unsigned */ #define SrcImmUByte (OpImmUByte << SrcShift)
#define SrcSI (0xa<<5) /* Source is in the DS:RSI */ #define SrcImmU (OpImmU << SrcShift)
#define SrcImmFAddr (0xb<<5) /* Source is immediate far address */ #define SrcSI (OpSI << SrcShift)
#define SrcMemFAddr (0xc<<5) /* Source is far address in memory */ #define SrcImmFAddr (OpImmFAddr << SrcShift)
#define SrcAcc (0xd<<5) /* Source Accumulator */ #define SrcMemFAddr (OpMemFAddr << SrcShift)
#define SrcImmU16 (0xe<<5) /* Immediate operand, unsigned, 16 bits */ #define SrcAcc (OpAcc << SrcShift)
#define SrcDX (0xf<<5) /* Source is in DX register */ #define SrcImmU16 (OpImmU16 << SrcShift)
#define SrcMask (0xf<<5) #define SrcDX (OpDX << SrcShift)
#define SrcMask (OpMask << SrcShift)
#define BitOp (1<<11) #define BitOp (1<<11)
#define MemAbs (1<<12) /* Memory operand is absolute displacement */ #define MemAbs (1<<12) /* Memory operand is absolute displacement */
#define String (1<<13) /* String instruction (rep capable) */ #define String (1<<13) /* String instruction (rep capable) */
@ -3354,13 +3362,14 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
break; break;
case OpMem: case OpMem:
case OpMem64: case OpMem64:
if (d == OpMem64)
ctxt->memop.bytes = 8;
else
ctxt->memop.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
mem_common:
*op = ctxt->memop; *op = ctxt->memop;
ctxt->memopp = op; ctxt->memopp = op;
if (d == OpMem64) if ((ctxt->d & BitOp) && op == &ctxt->dst)
op->bytes = 8;
else
op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
if (ctxt->d & BitOp)
fetch_bit_operand(ctxt); fetch_bit_operand(ctxt);
op->orig_val = op->val; op->orig_val = op->val;
break; break;
@ -3399,6 +3408,35 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
case OpImm: case OpImm:
rc = decode_imm(ctxt, op, imm_size(ctxt), true); rc = decode_imm(ctxt, op, imm_size(ctxt), true);
break; break;
case OpMem16:
ctxt->memop.bytes = 2;
goto mem_common;
case OpMem32:
ctxt->memop.bytes = 4;
goto mem_common;
case OpImmU16:
rc = decode_imm(ctxt, op, 2, false);
break;
case OpImmU:
rc = decode_imm(ctxt, op, imm_size(ctxt), false);
break;
case OpSI:
op->type = OP_MEM;
op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
op->addr.mem.ea =
register_address(ctxt, ctxt->regs[VCPU_REGS_RSI]);
op->addr.mem.seg = seg_override(ctxt);
op->val = 0;
break;
case OpImmFAddr:
op->type = OP_IMM;
op->addr.mem.ea = ctxt->_eip;
op->bytes = ctxt->op_bytes + 2;
insn_fetch_arr(op->valptr, op->bytes, ctxt);
break;
case OpMemFAddr:
ctxt->memop.bytes = ctxt->op_bytes + 2;
goto mem_common;
case OpImplicit: case OpImplicit:
/* Special instructions do their own operand decoding. */ /* Special instructions do their own operand decoding. */
default: default:
@ -3597,75 +3635,7 @@ done_prefixes:
* Decode and fetch the source operand: register, memory * Decode and fetch the source operand: register, memory
* or immediate. * or immediate.
*/ */
switch (ctxt->d & SrcMask) { rc = decode_operand(ctxt, &ctxt->src, (ctxt->d >> SrcShift) & OpMask);
case SrcNone:
break;
case SrcReg:
decode_register_operand(ctxt, &ctxt->src, 0);
break;
case SrcMem16:
ctxt->memop.bytes = 2;
goto srcmem_common;
case SrcMem32:
ctxt->memop.bytes = 4;
goto srcmem_common;
case SrcMem:
ctxt->memop.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
srcmem_common:
ctxt->src = ctxt->memop;
ctxt->memopp = &ctxt->src;
break;
case SrcImmU16:
rc = decode_imm(ctxt, &ctxt->src, 2, false);
break;
case SrcImm:
rc = decode_imm(ctxt, &ctxt->src, imm_size(ctxt), true);
break;
case SrcImmU:
rc = decode_imm(ctxt, &ctxt->src, imm_size(ctxt), false);
break;
case SrcImmByte:
rc = decode_imm(ctxt, &ctxt->src, 1, true);
break;
case SrcImmUByte:
rc = decode_imm(ctxt, &ctxt->src, 1, false);
break;
case SrcAcc:
ctxt->src.type = OP_REG;
ctxt->src.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
ctxt->src.addr.reg = &ctxt->regs[VCPU_REGS_RAX];
fetch_register_operand(&ctxt->src);
break;
case SrcOne:
ctxt->src.bytes = 1;
ctxt->src.val = 1;
break;
case SrcSI:
ctxt->src.type = OP_MEM;
ctxt->src.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
ctxt->src.addr.mem.ea =
register_address(ctxt, ctxt->regs[VCPU_REGS_RSI]);
ctxt->src.addr.mem.seg = seg_override(ctxt);
ctxt->src.val = 0;
break;
case SrcImmFAddr:
ctxt->src.type = OP_IMM;
ctxt->src.addr.mem.ea = ctxt->_eip;
ctxt->src.bytes = ctxt->op_bytes + 2;
insn_fetch_arr(ctxt->src.valptr, ctxt->src.bytes, ctxt);
break;
case SrcMemFAddr:
ctxt->memop.bytes = ctxt->op_bytes + 2;
goto srcmem_common;
break;
case SrcDX:
ctxt->src.type = OP_REG;
ctxt->src.bytes = 2;
ctxt->src.addr.reg = &ctxt->regs[VCPU_REGS_RDX];
fetch_register_operand(&ctxt->src);
break;
}
if (rc != X86EMUL_CONTINUE) if (rc != X86EMUL_CONTINUE)
goto done; goto done;