Skip to contentSkip to conversation

KVM: x86 emulator: add JrCXZ instruction emulation

PATCH New Wei Yongjun 3 participants 7 messages Aug 19, 2010 – Aug 24, 2010

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 KVM: x86 emulator: add JrCXZ instruction emulation

Add JrCXZ instruction emulation (opcode 0xe3)
Used by FreeBSD boot loader.

arch/x86/kvm/emulate.c +5 -1
index cbf6209..6ccc584 100644
@@ -2331,7 +2331,7 @@ static struct opcode opcode_table[256] = {
 	/* 0xD8 - 0xDF */
 	N, N, N, N, N, N, N, N,
 	/* 0xE0 - 0xE7 */
-	X3(D(SrcImmByte)), N,
+	X4(D(SrcImmByte)),
 	D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc),
 	D(ByteOp | SrcAcc | DstImmUByte), D(SrcAcc | DstImmUByte),
 	/* 0xE8 - 0xEF */
@@ -3092,6 +3092,10 @@ special_insn:
 		    (c->b == 0xe2 || test_cc(c->b ^ 0x5, ctxt->eflags)))
 			jmp_rel(c, c->src.val);
 		break;
+	case 0xe3:	/* jcxz/jecxz/jrcxz */
+		if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0)
+			jmp_rel(c, c->src.val);
+		break;
 	case 0xe4: 	/* inb */
 	case 0xe5: 	/* in */
 		goto do_io_in;
Signature · 1 line
1.7.0.4
#1 lore raw

PATCH 1/1 Add realmode test for jcxz instruction

x86/realmode.c +27 -0
index ce8fb18..0caf388 100644
@@ -1262,6 +1262,32 @@ void test_cbw(void)
 		print_serial("cwde test 1: PASS\n");
 }
 
+void test_jcxz(void)
+{
+	struct regs inregs = { 0 }, outregs;
+
+	MK_INSN(jcxz, "jcxz 1f\n\t"
+		      "mov $0x1234, %eax\n\t"
+		      "1:\n\t");
+	MK_INSN(jecxz, "jecxz 1f\n\t"
+		       "mov $0x1234, %eax\n\t"
+		       "1:\n\t");
+
+	exec_in_big_real_mode(&inregs, &outregs,
+			insn_jcxz, insn_jcxz_end - insn_jcxz);
+	if(!regs_equal(&inregs, &outregs, 0))
+		print_serial("JCXZ short Test 1: FAIL\n");
+	else
+		print_serial("JCXZ short Test 1: PASS\n");
+
+	exec_in_big_real_mode(&inregs, &outregs,
+			insn_jecxz, insn_jecxz_end - insn_jecxz);
+	if(!regs_equal(&inregs, &outregs, 0))
+		print_serial("JECXZ short Test 1: FAIL\n");
+	else
+		print_serial("JECXZ short Test 1: PASS\n");
+}
+
 void realmode_start(void)
 {
 	test_null();
@@ -1291,6 +1317,7 @@ void realmode_start(void)
 	test_idiv();
 	test_loopcc();
 	test_cbw();
+	test_jcxz();
 
 	exit(0);
 }
Signature · 1 line
1.7.0.4
#2 lore raw

Re: [PATCH] Add realmode test for jcxz instruction

Quoted 26 lines · Wei Yongjun
x86/realmode.c +16 -0
index ce8fb18..0caf388 100644
@@ -1262,6 +1262,32 @@ void test_cbw(void)
 		print_serial("cwde test 1: PASS\n");
 }
 
+void test_jcxz(void)
+{
+	struct regs inregs = { 0 }, outregs;
+
+	MK_INSN(jcxz, "jcxz 1f\n\t"
+		      "mov $0x1234, %eax\n\t"
+		      "1:\n\t");
+	MK_INSN(jecxz, "jecxz 1f\n\t"
+		       "mov $0x1234, %eax\n\t"
+		       "1:\n\t");
+
+	exec_in_big_real_mode(&inregs, &outregs,
+			insn_jcxz, insn_jcxz_end - insn_jcxz);
+	if(!regs_equal(&inregs, &outregs, 0))
+		print_serial("JCXZ short Test 1: FAIL\n");
+	else

x86/realmode.c void test_cbw(void) · line 1290

Quoted 10 lines
x86/realmode.c +10 -0
+		print_serial("JCXZ short Test 1: PASS\n");
+
+	exec_in_big_real_mode(&inregs, &outregs,
+			insn_jecxz, insn_jecxz_end - insn_jecxz);
+	if(!regs_equal(&inregs, &outregs, 0))
+		print_serial("JECXZ short Test 1: FAIL\n");
+	else
+		print_serial("JECXZ short Test 1: PASS\n");
+}
+

What about tests for jump-not-taken?

As a bonus, check jcxz with ecx=0x10000 and jecxz with ecx=0x10000.

Signature · 1 line
error compiling committee.c: too many arguments to function
#3 lore raw

PATCH v2 1/1 Add realmode test for jcxz instruction

---
 x86/realmode.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 62 insertions(+), 0 deletions(-)
x86/realmode.c +62 -0
index ce8fb18..75d77bd 100644
@@ -1262,6 +1262,67 @@ void test_cbw(void)
 		print_serial("cwde test 1: PASS\n");
 }
 
+void test_jcxz(void)
+{
+	struct regs inregs = { 0 }, outregs;
+
+	MK_INSN(jcxz1, "jcxz 1f\n\t"
+		       "mov $0x1234, %eax\n\t"
+		       "1:\n\t");
+	MK_INSN(jcxz2, "mov $0x100, %ecx\n\t"
+		       "jcxz 1f\n\t"
+		       "mov $0x1234, %eax\n\t"
+		       "mov $0, %ecx\n\t"
+		       "1:\n\t");
+	MK_INSN(jcxz3, "mov $0x10000, %ecx\n\t"
+		       "jcxz 1f\n\t"
+		       "mov $0x1234, %eax\n\t"
+		       "1:\n\t");
+	MK_INSN(jecxz1, "jecxz 1f\n\t"
+			"mov $0x1234, %eax\n\t"
+			"1:\n\t");
+	MK_INSN(jecxz2, "mov $0x10000, %ecx\n\t"
+			"jecxz 1f\n\t"
+			"mov $0x1234, %eax\n\t"
+			"mov $0, %ecx\n\t"
+			"1:\n\t");
+
+	exec_in_big_real_mode(&inregs, &outregs,
+			insn_jcxz1, insn_jcxz1_end - insn_jcxz1);
+	if(!regs_equal(&inregs, &outregs, 0))
+		print_serial("JCXZ short Test 1: FAIL\n");
+	else
+		print_serial("JCXZ short Test 1: PASS\n");
+
+	exec_in_big_real_mode(&inregs, &outregs,
+			insn_jcxz2, insn_jcxz2_end - insn_jcxz2);
+	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
+		print_serial("JCXZ short Test 2: FAIL\n");
+	else
+		print_serial("JCXZ short Test 2: PASS\n");
+
+	exec_in_big_real_mode(&inregs, &outregs,
+			insn_jcxz3, insn_jcxz3_end - insn_jcxz3);
+	if(!regs_equal(&inregs, &outregs, R_CX) || outregs.ecx != 0x10000)
+		print_serial("JCXZ short Test 3: FAIL\n");
+	else
+		print_serial("JCXZ short Test 3: PASS\n");
+
+	exec_in_big_real_mode(&inregs, &outregs,
+			insn_jecxz1, insn_jecxz1_end - insn_jecxz1);
+	if(!regs_equal(&inregs, &outregs, 0))
+		print_serial("JECXZ short Test 1: FAIL\n");
+	else
+		print_serial("JECXZ short Test 1: PASS\n");
+
+	exec_in_big_real_mode(&inregs, &outregs,
+			insn_jecxz2, insn_jecxz2_end - insn_jecxz2);
+	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
+		print_serial("JECXZ short Test 2: FAIL\n");
+	else
+		print_serial("JECXZ short Test 2: PASS\n");
+}
+
 void realmode_start(void)
 {
 	test_null();
@@ -1291,6 +1352,7 @@ void realmode_start(void)
 	test_idiv();
 	test_loopcc();
 	test_cbw();
+	test_jcxz();
 
 	exit(0);
 }
Signature · 1 line
1.7.0.4
#4 lore raw

Re: [PATCH v2] Add realmode test for jcxz instruction

Quoted 4 lines · Wei Yongjun
---
 x86/realmode.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 62 insertions(+), 0 deletions(-)

Please rebase.

#5 lore raw

PATCH v3 1/1 Add realmode test for jcxz instruction

---
v2 -> v3: rebased

---
 x86/realmode.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)
x86/realmode.c +42 -0
index 8c771fc..a833829 100644
@@ -1242,6 +1242,47 @@ void test_lds_lss()
 		outregs.ebx == desc.sel);
 }
 
+void test_jcxz(void)
+{
+	MK_INSN(jcxz1, "jcxz 1f\n\t"
+		       "mov $0x1234, %eax\n\t"
+		       "1:\n\t");
+	MK_INSN(jcxz2, "mov $0x100, %ecx\n\t"
+		       "jcxz 1f\n\t"
+		       "mov $0x1234, %eax\n\t"
+		       "mov $0, %ecx\n\t"
+		       "1:\n\t");
+	MK_INSN(jcxz3, "mov $0x10000, %ecx\n\t"
+		       "jcxz 1f\n\t"
+		       "mov $0x1234, %eax\n\t"
+		       "1:\n\t");
+	MK_INSN(jecxz1, "jecxz 1f\n\t"
+			"mov $0x1234, %eax\n\t"
+			"1:\n\t");
+	MK_INSN(jecxz2, "mov $0x10000, %ecx\n\t"
+			"jecxz 1f\n\t"
+			"mov $0x1234, %eax\n\t"
+			"mov $0, %ecx\n\t"
+			"1:\n\t");
+
+	inregs = (struct regs){ 0 };
+
+	exec_in_big_real_mode(&insn_jcxz1);
+	report("jcxz short 1", 0, 1);
+
+	exec_in_big_real_mode(&insn_jcxz2);
+	report("jcxz short 2", R_AX, outregs.eax == 0x1234);
+
+	exec_in_big_real_mode(&insn_jcxz3);
+	report("jcxz short 3", R_CX, outregs.ecx == 0x10000);
+
+	exec_in_big_real_mode(&insn_jecxz1);
+	report("jecxz short 1", 0, 1);
+
+	exec_in_big_real_mode(&insn_jecxz2);
+	report("jecxz short 2", R_AX, outregs.eax == 0x1234);
+}
+
 void realmode_start(void)
 {
 	test_null();
@@ -1274,6 +1315,7 @@ void realmode_start(void)
 	test_cwd_cdq();
 	test_das();
 	test_lds_lss();
+	test_jcxz();
 
 	exit(0);
 }
Signature · 1 line
1.7.0.4
#6 lore raw

Re: [PATCH v3] Add realmode test for jcxz instruction

Quoted 6 lines · Wei Yongjun

---
v2 -> v3: rebased

---
 x86/realmode.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)

Applied, thanks.