Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Apr 2014 15:11:11 +0000 (UTC)
From:      Tycho Nightingale <tychon@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r264501 - head/sys/amd64/vmm
Message-ID:  <201404151511.s3FFBBIW087669@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tychon
Date: Tue Apr 15 15:11:10 2014
New Revision: 264501
URL: http://svnweb.freebsd.org/changeset/base/264501

Log:
  Add support for emulating the byte move and sign extend instructions:
  "movsx r/m8, r32" and "movsx r/m8, r64".
  
  Approved by:	grehan (co-mentor)

Modified:
  head/sys/amd64/vmm/vmm_instruction_emul.c

Modified: head/sys/amd64/vmm/vmm_instruction_emul.c
==============================================================================
--- head/sys/amd64/vmm/vmm_instruction_emul.c	Tue Apr 15 14:55:56 2014	(r264500)
+++ head/sys/amd64/vmm/vmm_instruction_emul.c	Tue Apr 15 15:11:10 2014	(r264501)
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 enum {
 	VIE_OP_TYPE_NONE = 0,
 	VIE_OP_TYPE_MOV,
+	VIE_OP_TYPE_MOVSX,
 	VIE_OP_TYPE_MOVZX,
 	VIE_OP_TYPE_AND,
 	VIE_OP_TYPE_OR,
@@ -69,6 +70,10 @@ static const struct vie_op two_byte_opco
 		.op_byte = 0xB6,
 		.op_type = VIE_OP_TYPE_MOVZX,
 	},
+	[0xBE] = {
+		.op_byte = 0xBE,
+		.op_type = VIE_OP_TYPE_MOVSX,
+	},
 };
 
 static const struct vie_op one_byte_opcodes[256] = {
@@ -333,9 +338,9 @@ emulate_mov(void *vm, int vcpuid, uint64
  * - address size override is not supported
  */
 static int
-emulate_movzx(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
-	      mem_region_read_t memread, mem_region_write_t memwrite,
-	      void *arg)
+emulate_movx(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
+	     mem_region_read_t memread, mem_region_write_t memwrite,
+	     void *arg)
 {
 	int error, size;
 	enum vm_reg_name reg;
@@ -368,6 +373,32 @@ emulate_movzx(void *vm, int vcpuid, uint
 		/* write the result */
 		error = vie_update_register(vm, vcpuid, reg, val, size);
 		break;
+	case 0xBE:
+		/*
+		 * MOV and sign extend byte from mem (ModRM:r/m) to
+		 * reg (ModRM:reg).
+		 *
+		 * 0F BE/r		movsx r/m8, r32
+		 * REX.W + 0F BE/r	movsx r/m8, r64
+		 */
+
+		/* get the first operand */
+		error = memread(vm, vcpuid, gpa, &val, 1, arg);
+		if (error)
+			break;
+
+		/* get the second operand */
+		reg = gpr_map[vie->reg];
+
+		if (vie->rex_w)
+			size = 8;
+
+		/* sign extend byte */
+		val = (int8_t)val;
+
+		/* write the result */
+		error = vie_update_register(vm, vcpuid, reg, val, size);
+		break;
 	default:
 		break;
 	}
@@ -508,9 +539,10 @@ vmm_emulate_instruction(void *vm, int vc
 		error = emulate_mov(vm, vcpuid, gpa, vie,
 				    memread, memwrite, memarg);
 		break;
+	case VIE_OP_TYPE_MOVSX:
 	case VIE_OP_TYPE_MOVZX:
-		error = emulate_movzx(vm, vcpuid, gpa, vie,
-				      memread, memwrite, memarg);
+		error = emulate_movx(vm, vcpuid, gpa, vie,
+				     memread, memwrite, memarg);
 		break;
 	case VIE_OP_TYPE_AND:
 		error = emulate_and(vm, vcpuid, gpa, vie,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404151511.s3FFBBIW087669>