Browse Source

KVM: x86 emulator: add SrcImmU16 operand type

Used for RET NEAR instructions.

Signed-off-by: Avi Kivity <avi@redhat.com>
Avi Kivity 15 years ago
parent
commit
b250e60589
1 changed files with 9 additions and 3 deletions
  1. 9 3
      arch/x86/kvm/emulate.c

+ 9 - 3
arch/x86/kvm/emulate.c

@@ -72,6 +72,7 @@
 #define SrcImmFAddr (0xb<<4)	/* Source is immediate far address */
 #define SrcMemFAddr (0xc<<4)	/* Source is far address in memory */
 #define SrcAcc      (0xd<<4)	/* Source Accumulator */
+#define SrcImmU16   (0xe<<4)    /* Immediate operand, unsigned, 16 bits */
 #define SrcMask     (0xf<<4)
 /* Generic ModRM decode. */
 #define ModRM       (1<<8)
@@ -2678,13 +2679,17 @@ done_prefixes:
 	srcmem_common:
 		c->src = memop;
 		break;
+	case SrcImmU16:
+		c->src.bytes = 2;
+		goto srcimm;
 	case SrcImm:
 	case SrcImmU:
-		c->src.type = OP_IMM;
-		c->src.addr.mem = c->eip;
 		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
 		if (c->src.bytes == 8)
 			c->src.bytes = 4;
+	srcimm:
+		c->src.type = OP_IMM;
+		c->src.addr.mem = c->eip;
 		/* NB. Immediates are sign-extended as necessary. */
 		switch (c->src.bytes) {
 		case 1:
@@ -2697,7 +2702,8 @@ done_prefixes:
 			c->src.val = insn_fetch(s32, 4, c->eip);
 			break;
 		}
-		if ((c->d & SrcMask) == SrcImmU) {
+		if ((c->d & SrcMask) == SrcImmU
+		    || (c->d & SrcMask) == SrcImmU16) {
 			switch (c->src.bytes) {
 			case 1:
 				c->src.val &= 0xff;