xref: /kvm-unit-tests/x86/realmode.c (revision 0cbd5b0620d292b1fa1e5e732d0dbfb8293eef37)
17d36db35SAvi Kivity asm(".code16gcc");
27d36db35SAvi Kivity 
37d36db35SAvi Kivity typedef unsigned char u8;
47d36db35SAvi Kivity typedef unsigned short u16;
57d36db35SAvi Kivity typedef unsigned u32;
67d36db35SAvi Kivity typedef unsigned long long u64;
77d36db35SAvi Kivity 
87d36db35SAvi Kivity void test_function(void);
97d36db35SAvi Kivity 
107d36db35SAvi Kivity asm(
117d36db35SAvi Kivity 	"test_function: \n\t"
127d36db35SAvi Kivity 	"mov $0x1234, %eax \n\t"
137d36db35SAvi Kivity 	"ret"
147d36db35SAvi Kivity    );
157d36db35SAvi Kivity 
167d36db35SAvi Kivity static int strlen(const char *str)
177d36db35SAvi Kivity {
187d36db35SAvi Kivity 	int n;
197d36db35SAvi Kivity 
207d36db35SAvi Kivity 	for (n = 0; *str; ++str)
217d36db35SAvi Kivity 		++n;
227d36db35SAvi Kivity 	return n;
237d36db35SAvi Kivity }
247d36db35SAvi Kivity 
257d36db35SAvi Kivity static void print_serial(const char *buf)
267d36db35SAvi Kivity {
277d36db35SAvi Kivity 	unsigned long len = strlen(buf);
287d36db35SAvi Kivity 
297d36db35SAvi Kivity 	asm volatile ("cld; addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1));
307d36db35SAvi Kivity }
317d36db35SAvi Kivity 
327d36db35SAvi Kivity static void exit(int code)
337d36db35SAvi Kivity {
347d36db35SAvi Kivity         asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4));
357d36db35SAvi Kivity }
367d36db35SAvi Kivity 
377d36db35SAvi Kivity struct regs {
387d36db35SAvi Kivity 	u32 eax, ebx, ecx, edx;
397d36db35SAvi Kivity 	u32 esi, edi, esp, ebp;
407d36db35SAvi Kivity 	u32 eip, eflags;
417d36db35SAvi Kivity };
427d36db35SAvi Kivity 
437d36db35SAvi Kivity static u64 gdt[] = {
447d36db35SAvi Kivity 	0,
457d36db35SAvi Kivity 	0x00cf9b000000ffffull, // flat 32-bit code segment
467d36db35SAvi Kivity 	0x00cf93000000ffffull, // flat 32-bit data segment
477d36db35SAvi Kivity };
487d36db35SAvi Kivity 
497d36db35SAvi Kivity static struct {
507d36db35SAvi Kivity 	u16 limit;
517d36db35SAvi Kivity 	void *base;
527d36db35SAvi Kivity } __attribute__((packed)) gdt_descr = {
537d36db35SAvi Kivity 	sizeof(gdt) - 1,
547d36db35SAvi Kivity 	gdt,
557d36db35SAvi Kivity };
567d36db35SAvi Kivity 
577d36db35SAvi Kivity static void exec_in_big_real_mode(const struct regs *inregs,
587d36db35SAvi Kivity 				  struct regs *outregs,
597d36db35SAvi Kivity 				  const u8 *insn, int insn_len)
607d36db35SAvi Kivity {
617d36db35SAvi Kivity 	unsigned long tmp;
627d36db35SAvi Kivity 	static struct regs save;
637d36db35SAvi Kivity 	int i;
647d36db35SAvi Kivity 	extern u8 test_insn[], test_insn_end[];
657d36db35SAvi Kivity 
667d36db35SAvi Kivity 	for (i = 0; i < insn_len; ++i)
677d36db35SAvi Kivity 		test_insn[i] = insn[i];
687d36db35SAvi Kivity 	for (; i < test_insn_end - test_insn; ++i)
697d36db35SAvi Kivity 		test_insn[i] = 0x90; // nop
707d36db35SAvi Kivity 
717d36db35SAvi Kivity 	save = *inregs;
727d36db35SAvi Kivity 	asm volatile(
737d36db35SAvi Kivity 		"lgdtl %[gdt_descr] \n\t"
747d36db35SAvi Kivity 		"mov %%cr0, %[tmp] \n\t"
757d36db35SAvi Kivity 		"or $1, %[tmp] \n\t"
767d36db35SAvi Kivity 		"mov %[tmp], %%cr0 \n\t"
777d36db35SAvi Kivity 		"mov %[bigseg], %%gs \n\t"
787d36db35SAvi Kivity 		"and $-2, %[tmp] \n\t"
797d36db35SAvi Kivity 		"mov %[tmp], %%cr0 \n\t"
807d36db35SAvi Kivity 
8132001692SAvi Kivity                 "pushw %[save]+36; popfw \n\t"
827d36db35SAvi Kivity 		"xchg %%eax, %[save]+0 \n\t"
837d36db35SAvi Kivity 		"xchg %%ebx, %[save]+4 \n\t"
847d36db35SAvi Kivity 		"xchg %%ecx, %[save]+8 \n\t"
857d36db35SAvi Kivity 		"xchg %%edx, %[save]+12 \n\t"
867d36db35SAvi Kivity 		"xchg %%esi, %[save]+16 \n\t"
877d36db35SAvi Kivity 		"xchg %%edi, %[save]+20 \n\t"
887d36db35SAvi Kivity 		"xchg %%esp, %[save]+24 \n\t"
897d36db35SAvi Kivity 		"xchg %%ebp, %[save]+28 \n\t"
907d36db35SAvi Kivity 
917d36db35SAvi Kivity 		"test_insn: . = . + 32\n\t"
927d36db35SAvi Kivity 		"test_insn_end: \n\t"
937d36db35SAvi Kivity 
947d36db35SAvi Kivity 		"xchg %%eax, %[save]+0 \n\t"
957d36db35SAvi Kivity 		"xchg %%ebx, %[save]+4 \n\t"
967d36db35SAvi Kivity 		"xchg %%ecx, %[save]+8 \n\t"
977d36db35SAvi Kivity 		"xchg %%edx, %[save]+12 \n\t"
987d36db35SAvi Kivity 		"xchg %%esi, %[save]+16 \n\t"
997d36db35SAvi Kivity 		"xchg %%edi, %[save]+20 \n\t"
1007d36db35SAvi Kivity 		"xchg %%esp, %[save]+24 \n\t"
1017d36db35SAvi Kivity 		"xchg %%ebp, %[save]+28 \n\t"
1027d36db35SAvi Kivity 
1037d36db35SAvi Kivity 		/* Save EFLAGS in outregs*/
1047d36db35SAvi Kivity 		"pushfl \n\t"
1057d36db35SAvi Kivity 		"popl %[save]+36 \n\t"
1067d36db35SAvi Kivity 
1077d36db35SAvi Kivity 		"xor %[tmp], %[tmp] \n\t"
1087d36db35SAvi Kivity 		"mov %[tmp], %%gs \n\t"
1097d36db35SAvi Kivity 		: [tmp]"=&r"(tmp), [save]"+m"(save)
1107d36db35SAvi Kivity 		: [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16)
1117d36db35SAvi Kivity 		: "cc", "memory"
1127d36db35SAvi Kivity 		);
1137d36db35SAvi Kivity 	*outregs = save;
1147d36db35SAvi Kivity }
1157d36db35SAvi Kivity 
1167d36db35SAvi Kivity #define R_AX 1
1177d36db35SAvi Kivity #define R_BX 2
1187d36db35SAvi Kivity #define R_CX 4
1197d36db35SAvi Kivity #define R_DX 8
1207d36db35SAvi Kivity #define R_SI 16
1217d36db35SAvi Kivity #define R_DI 32
1227d36db35SAvi Kivity #define R_SP 64
1237d36db35SAvi Kivity #define R_BP 128
1247d36db35SAvi Kivity 
1257d36db35SAvi Kivity int regs_equal(const struct regs *r1, const struct regs *r2, int ignore)
1267d36db35SAvi Kivity {
1277d36db35SAvi Kivity 	const u32 *p1 = &r1->eax, *p2 = &r2->eax;  // yuck
1287d36db35SAvi Kivity 	int i;
1297d36db35SAvi Kivity 
1307d36db35SAvi Kivity 	for (i = 0; i < 8; ++i)
1317d36db35SAvi Kivity 		if (!(ignore & (1 << i)) && p1[i] != p2[i])
1327d36db35SAvi Kivity 			return 0;
1337d36db35SAvi Kivity 	return 1;
1347d36db35SAvi Kivity }
1357d36db35SAvi Kivity 
1367d36db35SAvi Kivity #define MK_INSN(name, str)                         \
1377d36db35SAvi Kivity 	asm (				           \
1387d36db35SAvi Kivity 		".text 1\n\t"                      \
1397d36db35SAvi Kivity 		"insn_" #name ": " str " \n\t"	   \
1407d36db35SAvi Kivity 		"insn_" #name "_end: \n\t"	   \
1417d36db35SAvi Kivity 		".text\n\t"                        \
1427d36db35SAvi Kivity 		);				   \
1437d36db35SAvi Kivity 	extern u8 insn_##name[], insn_##name##_end[]
1447d36db35SAvi Kivity 
1457d36db35SAvi Kivity void test_xchg(void)
1467d36db35SAvi Kivity {
1477d36db35SAvi Kivity 	struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}, outregs;
1487d36db35SAvi Kivity 
1497d36db35SAvi Kivity 	MK_INSN(xchg_test1, "xchg %eax,%eax\n\t");
1507d36db35SAvi Kivity 	MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t");
1517d36db35SAvi Kivity 	MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t");
1527d36db35SAvi Kivity 	MK_INSN(xchg_test4, "xchg %eax,%edx\n\t");
1537d36db35SAvi Kivity 	MK_INSN(xchg_test5, "xchg %eax,%esi\n\t");
1547d36db35SAvi Kivity 	MK_INSN(xchg_test6, "xchg %eax,%edi\n\t");
1557d36db35SAvi Kivity 	MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t");
1567d36db35SAvi Kivity 	MK_INSN(xchg_test8, "xchg %eax,%esp\n\t");
1577d36db35SAvi Kivity 
1587d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
1597d36db35SAvi Kivity 			      insn_xchg_test1,
1607d36db35SAvi Kivity                               insn_xchg_test1_end - insn_xchg_test1);
1617d36db35SAvi Kivity 
1627d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, 0))
1637d36db35SAvi Kivity 		print_serial("xchg test 1: FAIL\n");
1647d36db35SAvi Kivity 	else
1657d36db35SAvi Kivity 		print_serial("xchg test 1: PASS\n");
1667d36db35SAvi Kivity 
1677d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
1687d36db35SAvi Kivity 			      insn_xchg_test2,
1697d36db35SAvi Kivity                               insn_xchg_test2_end - insn_xchg_test2);
1707d36db35SAvi Kivity 
1717d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX | R_BX) ||
1727d36db35SAvi Kivity             outregs.eax != inregs.ebx ||
1737d36db35SAvi Kivity             outregs.ebx != inregs.eax)
1747d36db35SAvi Kivity 		print_serial("xchg test 2: FAIL\n");
1757d36db35SAvi Kivity 	else
1767d36db35SAvi Kivity 		print_serial("xchg test 2: PASS\n");
1777d36db35SAvi Kivity 
1787d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
1797d36db35SAvi Kivity 			      insn_xchg_test3,
1807d36db35SAvi Kivity                               insn_xchg_test3_end - insn_xchg_test3);
1817d36db35SAvi Kivity 
1827d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX) ||
1837d36db35SAvi Kivity             outregs.eax != inregs.ecx ||
1847d36db35SAvi Kivity             outregs.ecx != inregs.eax)
1857d36db35SAvi Kivity 		print_serial("xchg test 3: FAIL\n");
1867d36db35SAvi Kivity 	else
1877d36db35SAvi Kivity 		print_serial("xchg test 3: PASS\n");
1887d36db35SAvi Kivity 
1897d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
1907d36db35SAvi Kivity 			      insn_xchg_test4,
1917d36db35SAvi Kivity                               insn_xchg_test4_end - insn_xchg_test4);
1927d36db35SAvi Kivity 
1937d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX | R_DX) ||
1947d36db35SAvi Kivity             outregs.eax != inregs.edx ||
1957d36db35SAvi Kivity             outregs.edx != inregs.eax)
1967d36db35SAvi Kivity 		print_serial("xchg test 4: FAIL\n");
1977d36db35SAvi Kivity 	else
1987d36db35SAvi Kivity 		print_serial("xchg test 4: PASS\n");
1997d36db35SAvi Kivity 
2007d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
2017d36db35SAvi Kivity 			      insn_xchg_test5,
2027d36db35SAvi Kivity                               insn_xchg_test5_end - insn_xchg_test5);
2037d36db35SAvi Kivity 
2047d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX | R_SI) ||
2057d36db35SAvi Kivity             outregs.eax != inregs.esi ||
2067d36db35SAvi Kivity             outregs.esi != inregs.eax)
2077d36db35SAvi Kivity 		print_serial("xchg test 5: FAIL\n");
2087d36db35SAvi Kivity 	else
2097d36db35SAvi Kivity 		print_serial("xchg test 5: PASS\n");
2107d36db35SAvi Kivity 
2117d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
2127d36db35SAvi Kivity 			      insn_xchg_test6,
2137d36db35SAvi Kivity                               insn_xchg_test6_end - insn_xchg_test6);
2147d36db35SAvi Kivity 
2157d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX | R_DI) ||
2167d36db35SAvi Kivity             outregs.eax != inregs.edi ||
2177d36db35SAvi Kivity             outregs.edi != inregs.eax)
2187d36db35SAvi Kivity 		print_serial("xchg test 6: FAIL\n");
2197d36db35SAvi Kivity 	else
2207d36db35SAvi Kivity 		print_serial("xchg test 6: PASS\n");
2217d36db35SAvi Kivity 
2227d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
2237d36db35SAvi Kivity 			      insn_xchg_test7,
2247d36db35SAvi Kivity                               insn_xchg_test7_end - insn_xchg_test7);
2257d36db35SAvi Kivity 
2267d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX | R_BP) ||
2277d36db35SAvi Kivity             outregs.eax != inregs.ebp ||
2287d36db35SAvi Kivity             outregs.ebp != inregs.eax)
2297d36db35SAvi Kivity 		print_serial("xchg test 7: FAIL\n");
2307d36db35SAvi Kivity 	else
2317d36db35SAvi Kivity 		print_serial("xchg test 7: PASS\n");
2327d36db35SAvi Kivity 
2337d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
2347d36db35SAvi Kivity 			      insn_xchg_test8,
2357d36db35SAvi Kivity                               insn_xchg_test8_end - insn_xchg_test8);
2367d36db35SAvi Kivity 
2377d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX | R_SP) ||
2387d36db35SAvi Kivity             outregs.eax != inregs.esp ||
2397d36db35SAvi Kivity             outregs.esp != inregs.eax)
2407d36db35SAvi Kivity 		print_serial("xchg test 8: FAIL\n");
2417d36db35SAvi Kivity 	else
2427d36db35SAvi Kivity 		print_serial("xchg test 8: PASS\n");
2437d36db35SAvi Kivity }
2447d36db35SAvi Kivity 
2457d36db35SAvi Kivity void test_shld(void)
2467d36db35SAvi Kivity {
2477d36db35SAvi Kivity 	struct regs inregs = { .eax = 0xbe, .edx = 0xef000000 }, outregs;
2487d36db35SAvi Kivity 	MK_INSN(shld_test, "shld $8,%edx,%eax\n\t");
2497d36db35SAvi Kivity 
2507d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
2517d36db35SAvi Kivity 			      insn_shld_test,
2527d36db35SAvi Kivity 			      insn_shld_test_end - insn_shld_test);
2537d36db35SAvi Kivity 	if (outregs.eax != 0xbeef)
2547d36db35SAvi Kivity 		print_serial("shld: FAIL\n");
2557d36db35SAvi Kivity 	else
2567d36db35SAvi Kivity 		print_serial("shld: PASS\n");
2577d36db35SAvi Kivity }
2587d36db35SAvi Kivity 
2597d36db35SAvi Kivity void test_mov_imm(void)
2607d36db35SAvi Kivity {
2617d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
2627d36db35SAvi Kivity 	MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax");
2637d36db35SAvi Kivity 	MK_INSN(mov_r16_imm_1, "mov $1234, %ax");
2647d36db35SAvi Kivity 	MK_INSN(mov_r8_imm_1, "mov $0x12, %ah");
2657d36db35SAvi Kivity 	MK_INSN(mov_r8_imm_2, "mov $0x34, %al");
2667d36db35SAvi Kivity 	MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t");
2677d36db35SAvi Kivity 
2687d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
2697d36db35SAvi Kivity 			      insn_mov_r16_imm_1,
2707d36db35SAvi Kivity 			      insn_mov_r16_imm_1_end - insn_mov_r16_imm_1);
2717d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234)
2727d36db35SAvi Kivity 		print_serial("mov test 1: FAIL\n");
2737d36db35SAvi Kivity 	else
2747d36db35SAvi Kivity 		print_serial("mov test 1: PASS\n");
2757d36db35SAvi Kivity 
2767d36db35SAvi Kivity 	/* test mov $imm, %eax */
2777d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
2787d36db35SAvi Kivity 			      insn_mov_r32_imm_1,
2797d36db35SAvi Kivity 			      insn_mov_r32_imm_1_end - insn_mov_r32_imm_1);
2807d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567890)
2817d36db35SAvi Kivity 		print_serial("mov test 2: FAIL\n");
2827d36db35SAvi Kivity 	else
2837d36db35SAvi Kivity 		print_serial("mov test 2: PASS\n");
2847d36db35SAvi Kivity 
2857d36db35SAvi Kivity 	/* test mov $imm, %al/%ah */
2867d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
2877d36db35SAvi Kivity 			      insn_mov_r8_imm_1,
2887d36db35SAvi Kivity 			      insn_mov_r8_imm_1_end - insn_mov_r8_imm_1);
2897d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1200)
2907d36db35SAvi Kivity 		print_serial("mov test 3: FAIL\n");
2917d36db35SAvi Kivity 	else
2927d36db35SAvi Kivity 		print_serial("mov test 3: PASS\n");
2937d36db35SAvi Kivity 
2947d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
2957d36db35SAvi Kivity 			      insn_mov_r8_imm_2,
2967d36db35SAvi Kivity 			      insn_mov_r8_imm_2_end - insn_mov_r8_imm_2);
2977d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x34)
2987d36db35SAvi Kivity 		print_serial("mov test 4: FAIL\n");
2997d36db35SAvi Kivity 	else
3007d36db35SAvi Kivity 		print_serial("mov test 4: PASS\n");
3017d36db35SAvi Kivity 
3027d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
3037d36db35SAvi Kivity 			      insn_mov_r8_imm_3,
3047d36db35SAvi Kivity 			      insn_mov_r8_imm_3_end - insn_mov_r8_imm_3);
3057d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
3067d36db35SAvi Kivity 		print_serial("mov test 5: FAIL\n");
3077d36db35SAvi Kivity 	else
3087d36db35SAvi Kivity 		print_serial("mov test 5: PASS\n");
3097d36db35SAvi Kivity }
3107d36db35SAvi Kivity 
3117d36db35SAvi Kivity void test_sub_imm(void)
3127d36db35SAvi Kivity {
3137d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
3147d36db35SAvi Kivity 	MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t");
3157d36db35SAvi Kivity 	MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t");
3167d36db35SAvi Kivity 	MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t");
3177d36db35SAvi Kivity 	MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t");
3187d36db35SAvi Kivity 
3197d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
3207d36db35SAvi Kivity 			      insn_sub_r16_imm_1,
3217d36db35SAvi Kivity 			      insn_sub_r16_imm_1_end - insn_sub_r16_imm_1);
3227d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1224)
3237d36db35SAvi Kivity 		print_serial("sub test 1: FAIL\n");
3247d36db35SAvi Kivity 	else
3257d36db35SAvi Kivity 		print_serial("sub test 1: PASS\n");
3267d36db35SAvi Kivity 
3277d36db35SAvi Kivity 	/* test mov $imm, %eax */
3287d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
3297d36db35SAvi Kivity 			      insn_sub_r32_imm_1,
3307d36db35SAvi Kivity 			      insn_sub_r32_imm_1_end - insn_sub_r32_imm_1);
3317d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567880)
3327d36db35SAvi Kivity 		print_serial("sub test 2: FAIL\n");
3337d36db35SAvi Kivity 	else
3347d36db35SAvi Kivity 		print_serial("sub test 2: PASS\n");
3357d36db35SAvi Kivity 
3367d36db35SAvi Kivity 	/* test mov $imm, %al/%ah */
3377d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
3387d36db35SAvi Kivity 			      insn_sub_r8_imm_1,
3397d36db35SAvi Kivity 			      insn_sub_r8_imm_1_end - insn_sub_r8_imm_1);
3407d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x0200)
3417d36db35SAvi Kivity 		print_serial("sub test 3: FAIL\n");
3427d36db35SAvi Kivity 	else
3437d36db35SAvi Kivity 		print_serial("sub test 3: PASS\n");
3447d36db35SAvi Kivity 
3457d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
3467d36db35SAvi Kivity 			      insn_sub_r8_imm_2,
3477d36db35SAvi Kivity 			      insn_sub_r8_imm_2_end - insn_sub_r8_imm_2);
3487d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x24)
3497d36db35SAvi Kivity 		print_serial("sub test 4: FAIL\n");
3507d36db35SAvi Kivity 	else
3517d36db35SAvi Kivity 		print_serial("sub test 4: PASS\n");
3527d36db35SAvi Kivity }
3537d36db35SAvi Kivity 
3547d36db35SAvi Kivity 
3557d36db35SAvi Kivity void test_xor_imm(void)
3567d36db35SAvi Kivity {
3577d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
3587d36db35SAvi Kivity 	MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t");
3597d36db35SAvi Kivity 	MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t");
3607d36db35SAvi Kivity 	MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t");
3617d36db35SAvi Kivity 	MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t");
3627d36db35SAvi Kivity 
3637d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
3647d36db35SAvi Kivity 			      insn_xor_r16_imm_1,
3657d36db35SAvi Kivity 			      insn_xor_r16_imm_1_end - insn_xor_r16_imm_1);
3667d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0)
3677d36db35SAvi Kivity 		print_serial("xor test 1: FAIL\n");
3687d36db35SAvi Kivity 	else
3697d36db35SAvi Kivity 		print_serial("xor test 1: PASS\n");
3707d36db35SAvi Kivity 
3717d36db35SAvi Kivity 	/* test mov $imm, %eax */
3727d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
3737d36db35SAvi Kivity 			      insn_xor_r32_imm_1,
3747d36db35SAvi Kivity 			      insn_xor_r32_imm_1_end - insn_xor_r32_imm_1);
3757d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0)
3767d36db35SAvi Kivity 		print_serial("xor test 2: FAIL\n");
3777d36db35SAvi Kivity 	else
3787d36db35SAvi Kivity 		print_serial("xor test 2: PASS\n");
3797d36db35SAvi Kivity 
3807d36db35SAvi Kivity 	/* test mov $imm, %al/%ah */
3817d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
3827d36db35SAvi Kivity 			      insn_xor_r8_imm_1,
3837d36db35SAvi Kivity 			      insn_xor_r8_imm_1_end - insn_xor_r8_imm_1);
3847d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0)
3857d36db35SAvi Kivity 		print_serial("xor test 3: FAIL\n");
3867d36db35SAvi Kivity 	else
3877d36db35SAvi Kivity 		print_serial("xor test 3: PASS\n");
3887d36db35SAvi Kivity 
3897d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
3907d36db35SAvi Kivity 			      insn_xor_r8_imm_2,
3917d36db35SAvi Kivity 			      insn_xor_r8_imm_2_end - insn_xor_r8_imm_2);
3927d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0)
3937d36db35SAvi Kivity 		print_serial("xor test 4: FAIL\n");
3947d36db35SAvi Kivity 	else
3957d36db35SAvi Kivity 		print_serial("xor test 4: PASS\n");
3967d36db35SAvi Kivity }
3977d36db35SAvi Kivity 
3987d36db35SAvi Kivity void test_cmp_imm(void)
3997d36db35SAvi Kivity {
4007d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
4017d36db35SAvi Kivity 	MK_INSN(cmp_test1, "mov $0x34, %al\n\t"
4027d36db35SAvi Kivity 			   "cmp $0x34, %al\n\t");
4037d36db35SAvi Kivity 	MK_INSN(cmp_test2, "mov $0x34, %al\n\t"
4047d36db35SAvi Kivity 			   "cmp $0x39, %al\n\t");
4057d36db35SAvi Kivity 	MK_INSN(cmp_test3, "mov $0x34, %al\n\t"
4067d36db35SAvi Kivity 			   "cmp $0x24, %al\n\t");
4077d36db35SAvi Kivity 
4087d36db35SAvi Kivity 	/* test cmp imm8 with AL */
4097d36db35SAvi Kivity 	/* ZF: (bit 6) Zero Flag becomes 1 if an operation results
4107d36db35SAvi Kivity 	 * in a 0 writeback, or 0 register
4117d36db35SAvi Kivity 	 */
4127d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
4137d36db35SAvi Kivity 			      insn_cmp_test1,
4147d36db35SAvi Kivity 			      insn_cmp_test1_end - insn_cmp_test1);
4157d36db35SAvi Kivity 	if ((outregs.eflags & (1<<6)) != (1<<6))
4167d36db35SAvi Kivity 		print_serial("cmp test 1: FAIL\n");
4177d36db35SAvi Kivity 	else
4187d36db35SAvi Kivity 		print_serial("cmp test 1: PASS\n");
4197d36db35SAvi Kivity 
4207d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
4217d36db35SAvi Kivity 			      insn_cmp_test2,
4227d36db35SAvi Kivity 			      insn_cmp_test2_end - insn_cmp_test2);
4237d36db35SAvi Kivity 	if ((outregs.eflags & (1<<6)) != 0)
4247d36db35SAvi Kivity 		print_serial("cmp test 2: FAIL\n");
4257d36db35SAvi Kivity 	else
4267d36db35SAvi Kivity 		print_serial("cmp test 2: PASS\n");
4277d36db35SAvi Kivity 
4287d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
4297d36db35SAvi Kivity 			      insn_cmp_test3,
4307d36db35SAvi Kivity 			      insn_cmp_test3_end - insn_cmp_test3);
4317d36db35SAvi Kivity 	if ((outregs.eflags & (1<<6)) != 0)
4327d36db35SAvi Kivity 		print_serial("cmp test 3: FAIL\n");
4337d36db35SAvi Kivity 	else
4347d36db35SAvi Kivity 		print_serial("cmp test 3: PASS\n");
4357d36db35SAvi Kivity }
4367d36db35SAvi Kivity 
4377d36db35SAvi Kivity void test_add_imm(void)
4387d36db35SAvi Kivity {
4397d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
4407d36db35SAvi Kivity 	MK_INSN(add_test1, "mov $0x43211234, %eax \n\t"
4417d36db35SAvi Kivity 			   "add $0x12344321, %eax \n\t");
4427d36db35SAvi Kivity 	MK_INSN(add_test2, "mov $0x12, %eax \n\t"
4437d36db35SAvi Kivity 			   "add $0x21, %al\n\t");
4447d36db35SAvi Kivity 
4457d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
4467d36db35SAvi Kivity 			      insn_add_test1,
4477d36db35SAvi Kivity 			      insn_add_test1_end - insn_add_test1);
4487d36db35SAvi Kivity 	if (outregs.eax != 0x55555555)
4497d36db35SAvi Kivity 		print_serial("add test 1: FAIL\n");
4507d36db35SAvi Kivity 	else
4517d36db35SAvi Kivity 		print_serial("add test 1: PASS\n");
4527d36db35SAvi Kivity 
4537d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
4547d36db35SAvi Kivity 			      insn_add_test2,
4557d36db35SAvi Kivity 			      insn_add_test2_end - insn_add_test2);
4567d36db35SAvi Kivity 	if (outregs.eax != 0x33)
4577d36db35SAvi Kivity 		print_serial("add test 2: FAIL\n");
4587d36db35SAvi Kivity 	else
4597d36db35SAvi Kivity 		print_serial("add test 2: PASS\n");
4607d36db35SAvi Kivity }
4617d36db35SAvi Kivity 
4627d36db35SAvi Kivity void test_eflags_insn(void)
4637d36db35SAvi Kivity {
4647d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
4657d36db35SAvi Kivity 	MK_INSN(clc, "clc");
466b3261e48SMohammed Gamal 	MK_INSN(stc, "stc");
4677d36db35SAvi Kivity 	MK_INSN(cli, "cli");
4687d36db35SAvi Kivity 	MK_INSN(sti, "sti");
4697d36db35SAvi Kivity 	MK_INSN(cld, "cld");
4707d36db35SAvi Kivity 	MK_INSN(std, "std");
4717d36db35SAvi Kivity 
4727d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
4737d36db35SAvi Kivity 			      insn_clc,
4747d36db35SAvi Kivity 			      insn_clc_end - insn_clc);
4757d36db35SAvi Kivity 	if (outregs.eflags & 1)
4767d36db35SAvi Kivity 		print_serial("clc test: FAIL\n");
4777d36db35SAvi Kivity 	else
4787d36db35SAvi Kivity 		print_serial("clc test: PASS\n");
4797d36db35SAvi Kivity 
4807d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
481b3261e48SMohammed Gamal 			      insn_stc,
482b3261e48SMohammed Gamal 			      insn_stc_end - insn_stc);
483b3261e48SMohammed Gamal 	if (!(outregs.eflags & 1))
484b3261e48SMohammed Gamal 		print_serial("stc test: FAIL\n");
485b3261e48SMohammed Gamal 	else
486b3261e48SMohammed Gamal 		print_serial("stc test: PASS\n");
487b3261e48SMohammed Gamal 
488b3261e48SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
4897d36db35SAvi Kivity 			      insn_cli,
4907d36db35SAvi Kivity 			      insn_cli_end - insn_cli);
4917d36db35SAvi Kivity 	if (outregs.eflags & (1 << 9))
4927d36db35SAvi Kivity 		print_serial("cli test: FAIL\n");
4937d36db35SAvi Kivity 	else
4947d36db35SAvi Kivity 		print_serial("cli test: PASS\n");
4957d36db35SAvi Kivity 
4967d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
4977d36db35SAvi Kivity 			      insn_sti,
4987d36db35SAvi Kivity 			      insn_sti_end - insn_sti);
4997d36db35SAvi Kivity 	if (!(outregs.eflags & (1 << 9)))
5007d36db35SAvi Kivity 		print_serial("sti test: FAIL\n");
5017d36db35SAvi Kivity 	else
5027d36db35SAvi Kivity 		print_serial("sti test: PASS\n");
5037d36db35SAvi Kivity 
5047d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
5057d36db35SAvi Kivity 			      insn_cld,
5067d36db35SAvi Kivity 			      insn_cld_end - insn_cld);
5077d36db35SAvi Kivity 	if (outregs.eflags & (1 << 10))
5087d36db35SAvi Kivity 		print_serial("cld test: FAIL\n");
5097d36db35SAvi Kivity 	else
5107d36db35SAvi Kivity 		print_serial("cld test: PASS\n");
5117d36db35SAvi Kivity 
5127d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
5137d36db35SAvi Kivity 			      insn_std,
5147d36db35SAvi Kivity 			      insn_std_end - insn_std);
5157d36db35SAvi Kivity 	if (!(outregs.eflags & (1 << 10)))
5167d36db35SAvi Kivity 		print_serial("std test: FAIL\n");
5177d36db35SAvi Kivity 	else
5187d36db35SAvi Kivity 		print_serial("std test: PASS\n");
5197d36db35SAvi Kivity }
5207d36db35SAvi Kivity 
5217d36db35SAvi Kivity void test_io(void)
5227d36db35SAvi Kivity {
5237d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
5247d36db35SAvi Kivity 	MK_INSN(io_test1, "mov $0xff, %al \n\t"
5257d36db35SAvi Kivity 		          "out %al, $0xe0 \n\t"
5267d36db35SAvi Kivity 		          "mov $0x00, %al \n\t"
5277d36db35SAvi Kivity 			  "in $0xe0, %al \n\t");
5287d36db35SAvi Kivity 	MK_INSN(io_test2, "mov $0xffff, %ax \n\t"
5297d36db35SAvi Kivity 			  "out %ax, $0xe0 \n\t"
5307d36db35SAvi Kivity 			  "mov $0x0000, %ax \n\t"
5317d36db35SAvi Kivity 			  "in $0xe0, %ax \n\t");
5327d36db35SAvi Kivity 	MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t"
5337d36db35SAvi Kivity 			  "out %eax, $0xe0 \n\t"
5347d36db35SAvi Kivity 			  "mov $0x000000, %eax \n\t"
5357d36db35SAvi Kivity 			  "in $0xe0, %eax \n\t");
5367d36db35SAvi Kivity 	MK_INSN(io_test4, "mov $0xe0, %dx \n\t"
5377d36db35SAvi Kivity 			  "mov $0xff, %al \n\t"
5387d36db35SAvi Kivity 			  "out %al, %dx \n\t"
5397d36db35SAvi Kivity 			  "mov $0x00, %al \n\t"
5407d36db35SAvi Kivity 			  "in %dx, %al \n\t");
5417d36db35SAvi Kivity 	MK_INSN(io_test5, "mov $0xe0, %dx \n\t"
5427d36db35SAvi Kivity 			  "mov $0xffff, %ax \n\t"
5437d36db35SAvi Kivity 			  "out %ax, %dx \n\t"
5447d36db35SAvi Kivity 			  "mov $0x0000, %ax \n\t"
5457d36db35SAvi Kivity 			  "in %dx, %ax \n\t");
5467d36db35SAvi Kivity 	MK_INSN(io_test6, "mov $0xe0, %dx \n\t"
5477d36db35SAvi Kivity 			  "mov $0xffffffff, %eax \n\t"
5487d36db35SAvi Kivity 			  "out %eax, %dx \n\t"
5497d36db35SAvi Kivity 			  "mov $0x00000000, %eax \n\t"
5507d36db35SAvi Kivity 			  "in %dx, %eax \n\t");
5517d36db35SAvi Kivity 
5527d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
5537d36db35SAvi Kivity 			      insn_io_test1,
5547d36db35SAvi Kivity 			      insn_io_test1_end - insn_io_test1);
5557d36db35SAvi Kivity 
5567d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xff)
5577d36db35SAvi Kivity 		print_serial("I/O test 1: FAIL\n");
5587d36db35SAvi Kivity 	else
5597d36db35SAvi Kivity 		print_serial("I/O test 1: PASS\n");
5607d36db35SAvi Kivity 
5617d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
5627d36db35SAvi Kivity 			      insn_io_test2,
5637d36db35SAvi Kivity 			      insn_io_test2_end - insn_io_test2);
5647d36db35SAvi Kivity 
5657d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffff)
5667d36db35SAvi Kivity 		print_serial("I/O test 2: FAIL\n");
5677d36db35SAvi Kivity 	else
5687d36db35SAvi Kivity 		print_serial("I/O test 2: PASS\n");
5697d36db35SAvi Kivity 
5707d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
5717d36db35SAvi Kivity 			      insn_io_test3,
5727d36db35SAvi Kivity 			      insn_io_test3_end - insn_io_test3);
5737d36db35SAvi Kivity 
5747d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffffffff)
5757d36db35SAvi Kivity 		print_serial("I/O test 3: FAIL\n");
5767d36db35SAvi Kivity 	else
5777d36db35SAvi Kivity 		print_serial("I/O test 3: PASS\n");
5787d36db35SAvi Kivity 
5797d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
5807d36db35SAvi Kivity 			      insn_io_test4,
5817d36db35SAvi Kivity 			      insn_io_test4_end - insn_io_test4);
5827d36db35SAvi Kivity 
5837d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xff)
5847d36db35SAvi Kivity 		print_serial("I/O test 4: FAIL\n");
5857d36db35SAvi Kivity 	else
5867d36db35SAvi Kivity 		print_serial("I/O test 4: PASS\n");
5877d36db35SAvi Kivity 
5887d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
5897d36db35SAvi Kivity 			      insn_io_test5,
5907d36db35SAvi Kivity 			      insn_io_test5_end - insn_io_test5);
5917d36db35SAvi Kivity 
5927d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffff)
5937d36db35SAvi Kivity 		print_serial("I/O test 5: FAIL\n");
5947d36db35SAvi Kivity 	else
5957d36db35SAvi Kivity 		print_serial("I/O test 5: PASS\n");
5967d36db35SAvi Kivity 
5977d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
5987d36db35SAvi Kivity 			      insn_io_test6,
5997d36db35SAvi Kivity 			      insn_io_test6_end - insn_io_test6);
6007d36db35SAvi Kivity 
6017d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffffffff)
6027d36db35SAvi Kivity 		print_serial("I/O test 6: FAIL\n");
6037d36db35SAvi Kivity 	else
6047d36db35SAvi Kivity 		print_serial("I/O test 6: PASS\n");
6057d36db35SAvi Kivity }
6067d36db35SAvi Kivity 
6077d36db35SAvi Kivity void test_call(void)
6087d36db35SAvi Kivity {
6097d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
6107d36db35SAvi Kivity 	u32 esp[16];
6117d36db35SAvi Kivity 
6127d36db35SAvi Kivity 	inregs.esp = (u32)esp;
6137d36db35SAvi Kivity 
6147d36db35SAvi Kivity 	MK_INSN(call1, "mov $test_function, %eax \n\t"
6157d36db35SAvi Kivity 		       "call *%eax\n\t");
6167d36db35SAvi Kivity 	MK_INSN(call_near1, "jmp 2f\n\t"
6177d36db35SAvi Kivity 			    "1: mov $0x1234, %eax\n\t"
6187d36db35SAvi Kivity 			    "ret\n\t"
6197d36db35SAvi Kivity 			    "2: call 1b\t");
6207d36db35SAvi Kivity 	MK_INSN(call_near2, "call 1f\n\t"
6217d36db35SAvi Kivity 			    "jmp 2f\n\t"
6227d36db35SAvi Kivity 			    "1: mov $0x1234, %eax\n\t"
6237d36db35SAvi Kivity 			    "ret\n\t"
6247d36db35SAvi Kivity 			    "2:\t");
6257d36db35SAvi Kivity 
6267d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
6277d36db35SAvi Kivity 			      insn_call1,
6287d36db35SAvi Kivity 			      insn_call1_end - insn_call1);
6297d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
6307d36db35SAvi Kivity 		print_serial("Call Test 1: FAIL\n");
6317d36db35SAvi Kivity 	else
6327d36db35SAvi Kivity 		print_serial("Call Test 1: PASS\n");
6337d36db35SAvi Kivity 
6347d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
6357d36db35SAvi Kivity 			insn_call_near1, insn_call_near1_end - insn_call_near1);
6367d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
6377d36db35SAvi Kivity 		print_serial("Call near Test 1: FAIL\n");
6387d36db35SAvi Kivity 	else
6397d36db35SAvi Kivity 		print_serial("Call near Test 1: PASS\n");
6407d36db35SAvi Kivity 
6417d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
6427d36db35SAvi Kivity 			insn_call_near2, insn_call_near2_end - insn_call_near2);
6437d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
6447d36db35SAvi Kivity 		print_serial("Call near Test 2: FAIL\n");
6457d36db35SAvi Kivity 	else
6467d36db35SAvi Kivity 		print_serial("Call near Test 2: PASS\n");
6477d36db35SAvi Kivity }
6487d36db35SAvi Kivity 
6497d36db35SAvi Kivity void test_jcc_short(void)
6507d36db35SAvi Kivity {
6517d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
6527d36db35SAvi Kivity 	MK_INSN(jnz_short1, "jnz 1f\n\t"
6537d36db35SAvi Kivity 			    "mov $0x1234, %eax\n\t"
6547d36db35SAvi Kivity 		            "1:\n\t");
6557d36db35SAvi Kivity 	MK_INSN(jnz_short2, "1:\n\t"
6567d36db35SAvi Kivity 			    "cmp $0x1234, %eax\n\t"
6577d36db35SAvi Kivity 			    "mov $0x1234, %eax\n\t"
6587d36db35SAvi Kivity 		            "jnz 1b\n\t");
6597d36db35SAvi Kivity 	MK_INSN(jmp_short1, "jmp 1f\n\t"
6607d36db35SAvi Kivity 		      "mov $0x1234, %eax\n\t"
6617d36db35SAvi Kivity 		      "1:\n\t");
6627d36db35SAvi Kivity 
6637d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
6647d36db35SAvi Kivity 			insn_jnz_short1, insn_jnz_short1_end - insn_jnz_short1);
6657d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, 0))
6667d36db35SAvi Kivity 		print_serial("JNZ short Test 1: FAIL\n");
6677d36db35SAvi Kivity 	else
6687d36db35SAvi Kivity 		print_serial("JNZ short Test 1: PASS\n");
6697d36db35SAvi Kivity 
6707d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
6717d36db35SAvi Kivity 			insn_jnz_short2, insn_jnz_short2_end - insn_jnz_short2);
6727d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6)))
6737d36db35SAvi Kivity 		print_serial("JNZ short Test 2: FAIL\n");
6747d36db35SAvi Kivity 	else
6757d36db35SAvi Kivity 		print_serial("JNZ short Test 2: PASS\n");
6767d36db35SAvi Kivity 
6777d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
6787d36db35SAvi Kivity 			insn_jmp_short1, insn_jmp_short1_end - insn_jmp_short1);
6797d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, 0))
6807d36db35SAvi Kivity 		print_serial("JMP short Test 1: FAIL\n");
6817d36db35SAvi Kivity 	else
6827d36db35SAvi Kivity 		print_serial("JMP short Test 1: PASS\n");
6837d36db35SAvi Kivity }
6847d36db35SAvi Kivity 
6857d36db35SAvi Kivity void test_jcc_near(void)
6867d36db35SAvi Kivity {
6877d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
6887d36db35SAvi Kivity 	/* encode near jmp manually. gas will not do it if offsets < 127 byte */
6897d36db35SAvi Kivity 	MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t"
6907d36db35SAvi Kivity 		           "mov $0x1234, %eax\n\t");
6917d36db35SAvi Kivity 	MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t"
6927d36db35SAvi Kivity 			   "mov $0x1234, %eax\n\t"
6937d36db35SAvi Kivity 		           ".byte 0x0f, 0x85, 0xf0, 0xff\n\t");
6947d36db35SAvi Kivity 	MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t"
6957d36db35SAvi Kivity 		           "mov $0x1234, %eax\n\t");
6967d36db35SAvi Kivity 
6977d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
6987d36db35SAvi Kivity 			insn_jnz_near1, insn_jnz_near1_end - insn_jnz_near1);
6997d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, 0))
7007d36db35SAvi Kivity 		print_serial("JNZ near Test 1: FAIL\n");
7017d36db35SAvi Kivity 	else
7027d36db35SAvi Kivity 		print_serial("JNZ near Test 1: PASS\n");
7037d36db35SAvi Kivity 
7047d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
7057d36db35SAvi Kivity 			insn_jnz_near2, insn_jnz_near2_end - insn_jnz_near2);
7067d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6)))
7077d36db35SAvi Kivity 		print_serial("JNZ near Test 2: FAIL\n");
7087d36db35SAvi Kivity 	else
7097d36db35SAvi Kivity 		print_serial("JNZ near Test 2: PASS\n");
7107d36db35SAvi Kivity 
7117d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
7127d36db35SAvi Kivity 			insn_jmp_near1, insn_jmp_near1_end - insn_jmp_near1);
7137d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, 0))
7147d36db35SAvi Kivity 		print_serial("JMP near Test 1: FAIL\n");
7157d36db35SAvi Kivity 	else
7167d36db35SAvi Kivity 		print_serial("JMP near Test 1: PASS\n");
7177d36db35SAvi Kivity }
7187d36db35SAvi Kivity 
7197d36db35SAvi Kivity void test_long_jmp()
7207d36db35SAvi Kivity {
7217d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
7227d36db35SAvi Kivity 	u32 esp[16];
7237d36db35SAvi Kivity 
7247d36db35SAvi Kivity 	inregs.esp = (u32)esp;
7257d36db35SAvi Kivity 	MK_INSN(long_jmp, "call 1f\n\t"
7267d36db35SAvi Kivity 			  "jmp 2f\n\t"
7277d36db35SAvi Kivity 			  "1: jmp $0, $test_function\n\t"
7287d36db35SAvi Kivity 		          "2:\n\t");
7297d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
7307d36db35SAvi Kivity 			      insn_long_jmp,
7317d36db35SAvi Kivity 			      insn_long_jmp_end - insn_long_jmp);
7327d36db35SAvi Kivity 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
7337d36db35SAvi Kivity 		print_serial("Long JMP Test: FAIL\n");
7347d36db35SAvi Kivity 	else
7357d36db35SAvi Kivity 		print_serial("Long JMP Test: PASS\n");
7367d36db35SAvi Kivity }
737fa74f8a6SMohammed Gamal 
7387d36db35SAvi Kivity void test_push_pop()
7397d36db35SAvi Kivity {
7407d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
7417d36db35SAvi Kivity 	MK_INSN(push32, "mov $0x12345678, %eax\n\t"
7427d36db35SAvi Kivity 			"push %eax\n\t"
7437d36db35SAvi Kivity 			"pop %ebx\n\t");
7447d36db35SAvi Kivity 	MK_INSN(push16, "mov $0x1234, %ax\n\t"
7457d36db35SAvi Kivity 			"push %ax\n\t"
7467d36db35SAvi Kivity 			"pop %bx\n\t");
7477d36db35SAvi Kivity 
7487d36db35SAvi Kivity 	MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten
7497d36db35SAvi Kivity 			 "mov $0x123, %ax\n\t"
7507d36db35SAvi Kivity 			 "mov %ax, %es\n\t"
7517d36db35SAvi Kivity 			 "push %es\n\t"
7527d36db35SAvi Kivity 			 "pop %bx \n\t"
7537d36db35SAvi Kivity 			 );
7547d36db35SAvi Kivity 	MK_INSN(pop_es, "push %ax\n\t"
7557d36db35SAvi Kivity 			"pop %es\n\t"
7567d36db35SAvi Kivity 			"mov %es, %bx\n\t"
7577d36db35SAvi Kivity 			);
7587d36db35SAvi Kivity 	MK_INSN(push_pop_ss, "push %ss\n\t"
7597d36db35SAvi Kivity 			     "pushw %ax\n\t"
7607d36db35SAvi Kivity 			     "popw %ss\n\t"
7617d36db35SAvi Kivity 			     "mov %ss, %bx\n\t"
7627d36db35SAvi Kivity 			     "pop %ss\n\t"
7637d36db35SAvi Kivity 			);
7647d36db35SAvi Kivity 	MK_INSN(push_pop_fs, "push %fs\n\t"
7657d36db35SAvi Kivity 			     "pushl %eax\n\t"
7667d36db35SAvi Kivity 			     "popl %fs\n\t"
7677d36db35SAvi Kivity 			     "mov %fs, %ebx\n\t"
7687d36db35SAvi Kivity 			     "pop %fs\n\t"
7697d36db35SAvi Kivity 			);
7707d36db35SAvi Kivity 
7717d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
7727d36db35SAvi Kivity 			      insn_push32,
7737d36db35SAvi Kivity 			      insn_push32_end - insn_push32);
7747d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x12345678)
7757d36db35SAvi Kivity 		print_serial("Push/Pop Test 1: FAIL\n");
7767d36db35SAvi Kivity 	else
7777d36db35SAvi Kivity 		print_serial("Push/Pop Test 1: PASS\n");
7787d36db35SAvi Kivity 
7797d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
7807d36db35SAvi Kivity 			      insn_push16,
7817d36db35SAvi Kivity 			      insn_push16_end - insn_push16);
7827d36db35SAvi Kivity 
7837d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x1234)
7847d36db35SAvi Kivity 		print_serial("Push/Pop Test 2: FAIL\n");
7857d36db35SAvi Kivity 	else
7867d36db35SAvi Kivity 		print_serial("Push/Pop Test 2: PASS\n");
7877d36db35SAvi Kivity 
7887d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
7897d36db35SAvi Kivity 			      insn_push_es,
7907d36db35SAvi Kivity 			      insn_push_es_end - insn_push_es);
7917d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) ||  outregs.ebx != outregs.eax || outregs.eax != 0x123)
7927d36db35SAvi Kivity 		print_serial("Push/Pop Test 3: FAIL\n");
7937d36db35SAvi Kivity 	else
7947d36db35SAvi Kivity 		print_serial("Push/Pop Test 3: PASS\n");
7957d36db35SAvi Kivity 
7967d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
7977d36db35SAvi Kivity 			      insn_pop_es,
7987d36db35SAvi Kivity 			      insn_pop_es_end - insn_pop_es);
7997d36db35SAvi Kivity 
8007d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax)
8017d36db35SAvi Kivity 		print_serial("Push/Pop Test 4: FAIL\n");
8027d36db35SAvi Kivity 	else
8037d36db35SAvi Kivity 		print_serial("Push/Pop Test 4: PASS\n");
8047d36db35SAvi Kivity 
8057d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
8067d36db35SAvi Kivity 			      insn_push_pop_ss,
8077d36db35SAvi Kivity 			      insn_push_pop_ss_end - insn_push_pop_ss);
8087d36db35SAvi Kivity 
8097d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax)
8107d36db35SAvi Kivity 		print_serial("Push/Pop Test 5: FAIL\n");
8117d36db35SAvi Kivity 	else
8127d36db35SAvi Kivity 		print_serial("Push/Pop Test 5: PASS\n");
8137d36db35SAvi Kivity 
8147d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
8157d36db35SAvi Kivity 			      insn_push_pop_fs,
8167d36db35SAvi Kivity 			      insn_push_pop_fs_end - insn_push_pop_fs);
8177d36db35SAvi Kivity 
8187d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax)
8197d36db35SAvi Kivity 		print_serial("Push/Pop Test 6: FAIL\n");
8207d36db35SAvi Kivity 	else
8217d36db35SAvi Kivity 		print_serial("Push/Pop Test 6: PASS\n");
8227d36db35SAvi Kivity }
8237d36db35SAvi Kivity 
8247d36db35SAvi Kivity void test_null(void)
8257d36db35SAvi Kivity {
8267d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
8277d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, 0, 0);
8287d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, 0))
8297d36db35SAvi Kivity 		print_serial("null test: FAIL\n");
8307d36db35SAvi Kivity 	else
8317d36db35SAvi Kivity 		print_serial("null test: PASS\n");
8327d36db35SAvi Kivity }
8337d36db35SAvi Kivity 
8347d36db35SAvi Kivity struct {
8357d36db35SAvi Kivity     char stack[500];
8367d36db35SAvi Kivity     char top[];
8377d36db35SAvi Kivity } tmp_stack;
8387d36db35SAvi Kivity 
8397d36db35SAvi Kivity void test_pusha_popa()
8407d36db35SAvi Kivity {
8417d36db35SAvi Kivity 	struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = (unsigned long)&tmp_stack.top }, outregs;
8427d36db35SAvi Kivity 
8437d36db35SAvi Kivity 	MK_INSN(pusha, "pusha\n\t"
8447d36db35SAvi Kivity 		       "pop %edi\n\t"
8457d36db35SAvi Kivity 		       "pop %esi\n\t"
8467d36db35SAvi Kivity 		       "pop %ebp\n\t"
8477d36db35SAvi Kivity 		       "add $4, %esp\n\t"
8487d36db35SAvi Kivity 		       "pop %ebx\n\t"
8497d36db35SAvi Kivity 		       "pop %edx\n\t"
8507d36db35SAvi Kivity 		       "pop %ecx\n\t"
8517d36db35SAvi Kivity 		       "pop %eax\n\t"
8527d36db35SAvi Kivity 		       );
8537d36db35SAvi Kivity 
8547d36db35SAvi Kivity 	MK_INSN(popa, "push %eax\n\t"
8557d36db35SAvi Kivity 		      "push %ecx\n\t"
8567d36db35SAvi Kivity 		      "push %edx\n\t"
8577d36db35SAvi Kivity 		      "push %ebx\n\t"
8587d36db35SAvi Kivity 		      "push %esp\n\t"
8597d36db35SAvi Kivity 		      "push %ebp\n\t"
8607d36db35SAvi Kivity 		      "push %esi\n\t"
8617d36db35SAvi Kivity 		      "push %edi\n\t"
8627d36db35SAvi Kivity 		      "popa\n\t"
8637d36db35SAvi Kivity 		      );
8647d36db35SAvi Kivity 
8657d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
8667d36db35SAvi Kivity 			      insn_pusha,
8677d36db35SAvi Kivity 			      insn_pusha_end - insn_pusha);
8687d36db35SAvi Kivity 
8697d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, 0))
8707d36db35SAvi Kivity 		print_serial("Pusha/Popa Test1: FAIL\n");
8717d36db35SAvi Kivity 	else
8727d36db35SAvi Kivity 		print_serial("Pusha/Popa Test1: PASS\n");
8737d36db35SAvi Kivity 
8747d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
8757d36db35SAvi Kivity 			      insn_popa,
8767d36db35SAvi Kivity 			      insn_popa_end - insn_popa);
8777d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, 0))
8787d36db35SAvi Kivity 		print_serial("Pusha/Popa Test2: FAIL\n");
8797d36db35SAvi Kivity 	else
8807d36db35SAvi Kivity 		print_serial("Pusha/Popa Test2: PASS\n");
8817d36db35SAvi Kivity }
8827d36db35SAvi Kivity 
8837d36db35SAvi Kivity void test_iret()
8847d36db35SAvi Kivity {
8857d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
8867d36db35SAvi Kivity 
8877d36db35SAvi Kivity 	MK_INSN(iret32, "pushf\n\t"
8887d36db35SAvi Kivity 			"pushl %cs\n\t"
8897d36db35SAvi Kivity 			"call 1f\n\t" /* a near call will push eip onto the stack */
8907d36db35SAvi Kivity 			"jmp 2f\n\t"
8917d36db35SAvi Kivity 			"1: iret\n\t"
8927d36db35SAvi Kivity 			"2:\n\t"
8937d36db35SAvi Kivity 		     );
8947d36db35SAvi Kivity 
8957d36db35SAvi Kivity 	MK_INSN(iret16, "pushfw\n\t"
8967d36db35SAvi Kivity 			"pushw %cs\n\t"
8977d36db35SAvi Kivity 			"callw 1f\n\t"
8987d36db35SAvi Kivity 			"jmp 2f\n\t"
8997d36db35SAvi Kivity 			"1: iretw\n\t"
9007d36db35SAvi Kivity 			"2:\n\t");
9017d36db35SAvi Kivity 
9027d36db35SAvi Kivity 	MK_INSN(iret_flags32, "pushfl\n\t"
9037d36db35SAvi Kivity 			      "popl %eax\n\t"
9047d36db35SAvi Kivity 			      "andl $~0x2, %eax\n\t"
9057d36db35SAvi Kivity 			      "orl $0xffc08028, %eax\n\t"
9067d36db35SAvi Kivity 			      "pushl %eax\n\t"
9077d36db35SAvi Kivity 			      "pushl %cs\n\t"
9087d36db35SAvi Kivity 			      "call 1f\n\t"
9097d36db35SAvi Kivity 			      "jmp 2f\n\t"
9107d36db35SAvi Kivity 			      "1: iret\n\t"
9117d36db35SAvi Kivity 			      "2:\n\t");
9127d36db35SAvi Kivity 
9137d36db35SAvi Kivity 	MK_INSN(iret_flags16, "pushfw\n\t"
9147d36db35SAvi Kivity 			      "popw %ax\n\t"
9157d36db35SAvi Kivity 			      "and $~0x2, %ax\n\t"
9167d36db35SAvi Kivity 			      "or $0x8028, %ax\n\t"
9177d36db35SAvi Kivity 			      "pushw %ax\n\t"
9187d36db35SAvi Kivity 			      "pushw %cs\n\t"
9197d36db35SAvi Kivity 			      "callw 1f\n\t"
9207d36db35SAvi Kivity 			      "jmp 2f\n\t"
9217d36db35SAvi Kivity 			      "1: iretw\n\t"
9227d36db35SAvi Kivity 			      "2:\n\t");
9237d36db35SAvi Kivity 
9247d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
9257d36db35SAvi Kivity 			      insn_iret32,
9267d36db35SAvi Kivity 			      insn_iret32_end - insn_iret32);
9277d36db35SAvi Kivity 
9287d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, 0))
9297d36db35SAvi Kivity 		print_serial("iret Test 1: FAIL\n");
9307d36db35SAvi Kivity 	else
9317d36db35SAvi Kivity 		print_serial("iret Test 1: PASS\n");
9327d36db35SAvi Kivity 
9337d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
9347d36db35SAvi Kivity 			      insn_iret16,
9357d36db35SAvi Kivity 			      insn_iret16_end - insn_iret16);
9367d36db35SAvi Kivity 
9377d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, 0))
9387d36db35SAvi Kivity 		print_serial("iret Test 2: FAIL\n");
9397d36db35SAvi Kivity 	else
9407d36db35SAvi Kivity 		print_serial("iret Test 2: PASS\n");
9417d36db35SAvi Kivity 
9427d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
9437d36db35SAvi Kivity 			      insn_iret_flags32,
9447d36db35SAvi Kivity 			      insn_iret_flags32_end - insn_iret_flags32);
9457d36db35SAvi Kivity 
9467d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX))
9477d36db35SAvi Kivity 		print_serial("iret Test 3: FAIL\n");
9487d36db35SAvi Kivity 	else
9497d36db35SAvi Kivity 		print_serial("iret Test 3: PASS\n");
9507d36db35SAvi Kivity 
9517d36db35SAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
9527d36db35SAvi Kivity 			      insn_iret_flags16,
9537d36db35SAvi Kivity 			      insn_iret_flags16_end - insn_iret_flags16);
9547d36db35SAvi Kivity 
9557d36db35SAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX))
9567d36db35SAvi Kivity 		print_serial("iret Test 4: FAIL\n");
9577d36db35SAvi Kivity 	else
9587d36db35SAvi Kivity 		print_serial("iret Test 4: PASS\n");
9597d36db35SAvi Kivity }
9607d36db35SAvi Kivity 
96196b9ca1eSMohammed Gamal void test_int()
96296b9ca1eSMohammed Gamal {
96396b9ca1eSMohammed Gamal 	struct regs inregs = { 0 }, outregs;
96496b9ca1eSMohammed Gamal 
96596b9ca1eSMohammed Gamal 	*(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */
96696b9ca1eSMohammed Gamal 	*(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */
96796b9ca1eSMohammed Gamal 
96896b9ca1eSMohammed Gamal 	MK_INSN(int11, "int $0x11\n\t");
96996b9ca1eSMohammed Gamal 
97096b9ca1eSMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
97196b9ca1eSMohammed Gamal 			      insn_int11,
97296b9ca1eSMohammed Gamal 			      insn_int11_end - insn_int11);
97396b9ca1eSMohammed Gamal 
97496b9ca1eSMohammed Gamal 	if (!regs_equal(&inregs, &outregs, 0))
97596b9ca1eSMohammed Gamal 		print_serial("int Test 1: FAIL\n");
97696b9ca1eSMohammed Gamal 	else
97796b9ca1eSMohammed Gamal 		print_serial("int Test 1: PASS\n");
97896b9ca1eSMohammed Gamal }
97996b9ca1eSMohammed Gamal 
980fa74f8a6SMohammed Gamal void test_imul()
981fa74f8a6SMohammed Gamal {
982fa74f8a6SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
983fa74f8a6SMohammed Gamal 
984fa74f8a6SMohammed Gamal 	MK_INSN(imul8_1, "mov $2, %al\n\t"
985fa74f8a6SMohammed Gamal 			"mov $-4, %cx\n\t"
986fa74f8a6SMohammed Gamal 			"imul %cl\n\t");
987fa74f8a6SMohammed Gamal 
988fa74f8a6SMohammed Gamal 	MK_INSN(imul16_1, "mov $2, %ax\n\t"
989fa74f8a6SMohammed Gamal 		      "mov $-4, %cx\n\t"
990fa74f8a6SMohammed Gamal 		      "imul %cx\n\t");
991fa74f8a6SMohammed Gamal 
992fa74f8a6SMohammed Gamal 	MK_INSN(imul32_1, "mov $2, %eax\n\t"
993fa74f8a6SMohammed Gamal 		       "mov $-4, %ecx\n\t"
994fa74f8a6SMohammed Gamal 		       "imul %ecx\n\t");
995fa74f8a6SMohammed Gamal 
996fa74f8a6SMohammed Gamal 	MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t"
997fa74f8a6SMohammed Gamal 			"mov $4, %cx\n\t"
998fa74f8a6SMohammed Gamal 			"imul %cl\n\t");
999fa74f8a6SMohammed Gamal 
1000fa74f8a6SMohammed Gamal 	MK_INSN(imul16_2, "mov $2, %ax\n\t"
1001fa74f8a6SMohammed Gamal 			"mov $4, %cx\n\t"
1002fa74f8a6SMohammed Gamal 			"imul %cx\n\t");
1003fa74f8a6SMohammed Gamal 
1004fa74f8a6SMohammed Gamal 	MK_INSN(imul32_2, "mov $2, %eax\n\t"
1005fa74f8a6SMohammed Gamal 			"mov $4, %ecx\n\t"
1006fa74f8a6SMohammed Gamal 			"imul %ecx\n\t");
1007fa74f8a6SMohammed Gamal 
1008fa74f8a6SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1009fa74f8a6SMohammed Gamal 			      insn_imul8_1,
1010fa74f8a6SMohammed Gamal 			      insn_imul8_1_end - insn_imul8_1);
1011fa74f8a6SMohammed Gamal 
1012fa74f8a6SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != (u8)-8)
1013fa74f8a6SMohammed Gamal 		print_serial("imul Test 1: FAIL\n");
1014fa74f8a6SMohammed Gamal 	else
1015fa74f8a6SMohammed Gamal 		print_serial("imul Test 1: PASS\n");
1016fa74f8a6SMohammed Gamal 
1017fa74f8a6SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1018fa74f8a6SMohammed Gamal 			      insn_imul16_1,
1019fa74f8a6SMohammed Gamal 			      insn_imul16_1_end - insn_imul16_1);
1020fa74f8a6SMohammed Gamal 
1021fa74f8a6SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-8)
1022fa74f8a6SMohammed Gamal 		print_serial("imul Test 2: FAIL\n");
1023fa74f8a6SMohammed Gamal 	else
1024fa74f8a6SMohammed Gamal 		print_serial("imul Test 2: PASS\n");
1025fa74f8a6SMohammed Gamal 
1026fa74f8a6SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1027fa74f8a6SMohammed Gamal 			      insn_imul32_1,
1028fa74f8a6SMohammed Gamal 			      insn_imul32_1_end - insn_imul32_1);
1029fa74f8a6SMohammed Gamal 
1030fa74f8a6SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-8)
1031fa74f8a6SMohammed Gamal 		print_serial("imul Test 3: FAIL\n");
1032fa74f8a6SMohammed Gamal 	else
1033fa74f8a6SMohammed Gamal 		print_serial("imul Test 3: PASS\n");
1034fa74f8a6SMohammed Gamal 
1035fa74f8a6SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1036fa74f8a6SMohammed Gamal 			      insn_imul8_2,
1037fa74f8a6SMohammed Gamal 			      insn_imul8_2_end - insn_imul8_2);
1038fa74f8a6SMohammed Gamal 
1039fa74f8a6SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xffff) != 8 ||
1040fa74f8a6SMohammed Gamal 	     (outregs.eax & 0xffff0000) != 0x12340000)
1041fa74f8a6SMohammed Gamal 		print_serial("imul Test 4: FAIL\n");
1042fa74f8a6SMohammed Gamal 	else
1043fa74f8a6SMohammed Gamal 		print_serial("imul Test 4: PASS\n");
1044fa74f8a6SMohammed Gamal 
1045fa74f8a6SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1046fa74f8a6SMohammed Gamal 			      insn_imul16_2,
1047fa74f8a6SMohammed Gamal 			      insn_imul16_2_end - insn_imul16_2);
1048fa74f8a6SMohammed Gamal 
1049fa74f8a6SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8)
1050fa74f8a6SMohammed Gamal 		print_serial("imul Test 5: FAIL\n");
1051fa74f8a6SMohammed Gamal 	else
1052fa74f8a6SMohammed Gamal 		print_serial("imul Test 5: PASS\n");
1053fa74f8a6SMohammed Gamal 
1054fa74f8a6SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1055fa74f8a6SMohammed Gamal 			      insn_imul32_2,
1056fa74f8a6SMohammed Gamal 			      insn_imul32_2_end - insn_imul32_2);
1057fa74f8a6SMohammed Gamal 
1058fa74f8a6SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8)
1059fa74f8a6SMohammed Gamal 		print_serial("imul Test 6: FAIL\n");
1060fa74f8a6SMohammed Gamal 	else
1061fa74f8a6SMohammed Gamal 		print_serial("imul Test 6: PASS\n");
1062fa74f8a6SMohammed Gamal }
1063fa74f8a6SMohammed Gamal 
106459317bd1SMohammed Gamal void test_mul()
106559317bd1SMohammed Gamal {
106659317bd1SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
106759317bd1SMohammed Gamal 
106859317bd1SMohammed Gamal 	MK_INSN(mul8, "mov $2, %al\n\t"
106959317bd1SMohammed Gamal 			"mov $4, %cx\n\t"
107059317bd1SMohammed Gamal 			"imul %cl\n\t");
107159317bd1SMohammed Gamal 
107259317bd1SMohammed Gamal 	MK_INSN(mul16, "mov $2, %ax\n\t"
107359317bd1SMohammed Gamal 			"mov $4, %cx\n\t"
107459317bd1SMohammed Gamal 			"imul %cx\n\t");
107559317bd1SMohammed Gamal 
107659317bd1SMohammed Gamal 	MK_INSN(mul32, "mov $2, %eax\n\t"
107759317bd1SMohammed Gamal 			"mov $4, %ecx\n\t"
107859317bd1SMohammed Gamal 			"imul %ecx\n\t");
107959317bd1SMohammed Gamal 
108059317bd1SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
108159317bd1SMohammed Gamal 			      insn_mul8,
108259317bd1SMohammed Gamal 			      insn_mul8_end - insn_mul8);
108359317bd1SMohammed Gamal 
108459317bd1SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != 8)
108559317bd1SMohammed Gamal 		print_serial("mul Test 1: FAIL\n");
108659317bd1SMohammed Gamal 	else
108759317bd1SMohammed Gamal 		print_serial("mul Test 1: PASS\n");
108859317bd1SMohammed Gamal 
108959317bd1SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
109059317bd1SMohammed Gamal 			      insn_mul16,
109159317bd1SMohammed Gamal 			      insn_mul16_end - insn_mul16);
109259317bd1SMohammed Gamal 
109359317bd1SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8)
109459317bd1SMohammed Gamal 		print_serial("mul Test 2: FAIL\n");
109559317bd1SMohammed Gamal 	else
109659317bd1SMohammed Gamal 		print_serial("mul Test 2: PASS\n");
109759317bd1SMohammed Gamal 
109859317bd1SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
109959317bd1SMohammed Gamal 			      insn_mul32,
110059317bd1SMohammed Gamal 			      insn_mul32_end - insn_mul32);
110159317bd1SMohammed Gamal 
110259317bd1SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8)
110359317bd1SMohammed Gamal 		print_serial("mul Test 3: FAIL\n");
110459317bd1SMohammed Gamal 	else
110559317bd1SMohammed Gamal 		print_serial("mul Test 3: PASS\n");
110659317bd1SMohammed Gamal }
110759317bd1SMohammed Gamal 
11080d4c7614SMohammed Gamal void test_div()
11090d4c7614SMohammed Gamal {
11100d4c7614SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
11110d4c7614SMohammed Gamal 
11120d4c7614SMohammed Gamal 	MK_INSN(div8, "mov $257, %ax\n\t"
11130d4c7614SMohammed Gamal 			"mov $2, %cl\n\t"
11140d4c7614SMohammed Gamal 			"div %cl\n\t");
11150d4c7614SMohammed Gamal 
11160d4c7614SMohammed Gamal 	MK_INSN(div16, "mov $512, %ax\n\t"
11170d4c7614SMohammed Gamal 			"mov $5, %cx\n\t"
11180d4c7614SMohammed Gamal 			"div %cx\n\t");
11190d4c7614SMohammed Gamal 
11200d4c7614SMohammed Gamal 	MK_INSN(div32, "mov $512, %eax\n\t"
11210d4c7614SMohammed Gamal 			"mov $5, %ecx\n\t"
11220d4c7614SMohammed Gamal 			"div %ecx\n\t");
11230d4c7614SMohammed Gamal 
11240d4c7614SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
11250d4c7614SMohammed Gamal 			     insn_div8,
11260d4c7614SMohammed Gamal 			     insn_div8_end - insn_div8);
11270d4c7614SMohammed Gamal 
11280d4c7614SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 384)
11290d4c7614SMohammed Gamal 		print_serial("div Test 1: FAIL\n");
11300d4c7614SMohammed Gamal 	else
11310d4c7614SMohammed Gamal 		print_serial("div Test 1: PASS\n");
11320d4c7614SMohammed Gamal 
11330d4c7614SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
11340d4c7614SMohammed Gamal 			      insn_div16,
11350d4c7614SMohammed Gamal 			      insn_div16_end - insn_div16);
11360d4c7614SMohammed Gamal 
11370d4c7614SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 ||
11380d4c7614SMohammed Gamal 	    outregs.edx != 2)
11390d4c7614SMohammed Gamal 		print_serial("div Test 2: FAIL\n");
11400d4c7614SMohammed Gamal 	else
11410d4c7614SMohammed Gamal 		print_serial("div Test 2: PASS\n");
11420d4c7614SMohammed Gamal 
11430d4c7614SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
11440d4c7614SMohammed Gamal 			      insn_div32,
11450d4c7614SMohammed Gamal 			      insn_div32_end - insn_div32);
11460d4c7614SMohammed Gamal 
11470d4c7614SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 ||
11480d4c7614SMohammed Gamal 	    outregs.edx != 2)
11490d4c7614SMohammed Gamal 		print_serial("div Test 3: FAIL\n");
11500d4c7614SMohammed Gamal 	else
11510d4c7614SMohammed Gamal 		print_serial("div Test 3: PASS\n");
11520d4c7614SMohammed Gamal }
11530d4c7614SMohammed Gamal 
11540d4c7614SMohammed Gamal void test_idiv()
11550d4c7614SMohammed Gamal {
11560d4c7614SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
11570d4c7614SMohammed Gamal 
11580d4c7614SMohammed Gamal 	MK_INSN(idiv8, "mov $256, %ax\n\t"
11590d4c7614SMohammed Gamal 			"mov $-2, %cl\n\t"
11600d4c7614SMohammed Gamal 			"idiv %cl\n\t");
11610d4c7614SMohammed Gamal 
11620d4c7614SMohammed Gamal 	MK_INSN(idiv16, "mov $512, %ax\n\t"
11630d4c7614SMohammed Gamal 			"mov $-2, %cx\n\t"
11640d4c7614SMohammed Gamal 			"idiv %cx\n\t");
11650d4c7614SMohammed Gamal 
11660d4c7614SMohammed Gamal 	MK_INSN(idiv32, "mov $512, %eax\n\t"
11670d4c7614SMohammed Gamal 			"mov $-2, %ecx\n\t"
11680d4c7614SMohammed Gamal 			"idiv %ecx\n\t");
11690d4c7614SMohammed Gamal 
11700d4c7614SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
11710d4c7614SMohammed Gamal 			     insn_idiv8,
11720d4c7614SMohammed Gamal 			     insn_idiv8_end - insn_idiv8);
11730d4c7614SMohammed Gamal 
11740d4c7614SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u8)-128)
11750d4c7614SMohammed Gamal 		print_serial("idiv Test 1: FAIL\n");
11760d4c7614SMohammed Gamal 	else
11770d4c7614SMohammed Gamal 		print_serial("idiv Test 1: PASS\n");
11780d4c7614SMohammed Gamal 
11790d4c7614SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
11800d4c7614SMohammed Gamal 			      insn_idiv16,
11810d4c7614SMohammed Gamal 			      insn_idiv16_end - insn_idiv16);
11820d4c7614SMohammed Gamal 
11830d4c7614SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-256)
11840d4c7614SMohammed Gamal 		print_serial("idiv Test 2: FAIL\n");
11850d4c7614SMohammed Gamal 	else
11860d4c7614SMohammed Gamal 		print_serial("idiv Test 2: PASS\n");
11870d4c7614SMohammed Gamal 
11880d4c7614SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
11890d4c7614SMohammed Gamal 			      insn_idiv32,
11900d4c7614SMohammed Gamal 			      insn_idiv32_end - insn_idiv32);
11910d4c7614SMohammed Gamal 
11920d4c7614SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-256)
11930d4c7614SMohammed Gamal 		print_serial("idiv Test 3: FAIL\n");
11940d4c7614SMohammed Gamal 	else
11950d4c7614SMohammed Gamal 		print_serial("idiv Test 3: PASS\n");
11960d4c7614SMohammed Gamal }
11970d4c7614SMohammed Gamal 
11986e293cf5SWei Yongjun void test_cbw(void)
11996e293cf5SWei Yongjun {
12006e293cf5SWei Yongjun 	struct regs inregs = { 0 }, outregs;
12016e293cf5SWei Yongjun 
12026e293cf5SWei Yongjun 	MK_INSN(cbw, "mov $0xFE, %eax \n\t"
12036e293cf5SWei Yongjun 		     "cbw\n\t");
12046e293cf5SWei Yongjun 	MK_INSN(cwde, "mov $0xFFFE, %eax \n\t"
12056e293cf5SWei Yongjun 		      "cwde\n\t");
12066e293cf5SWei Yongjun 
12076e293cf5SWei Yongjun 	exec_in_big_real_mode(&inregs, &outregs,
12086e293cf5SWei Yongjun 			      insn_cbw,
12096e293cf5SWei Yongjun 			      insn_cbw_end - insn_cbw);
12106e293cf5SWei Yongjun 	if (outregs.eax != 0xFFFE)
12116e293cf5SWei Yongjun 		print_serial("cbw test1: FAIL\n");
12126e293cf5SWei Yongjun 	else
12136e293cf5SWei Yongjun 		print_serial("cbw test 1: PASS\n");
12146e293cf5SWei Yongjun 
12156e293cf5SWei Yongjun 	exec_in_big_real_mode(&inregs, &outregs,
12166e293cf5SWei Yongjun 			      insn_cwde,
12176e293cf5SWei Yongjun 			      insn_cwde_end - insn_cwde);
12186e293cf5SWei Yongjun 	if (outregs.eax != 0xFFFFFFFE)
12196e293cf5SWei Yongjun 		print_serial("cwde test1: FAIL\n");
12206e293cf5SWei Yongjun 	else
12216e293cf5SWei Yongjun 		print_serial("cwde test 1: PASS\n");
12226e293cf5SWei Yongjun }
12236e293cf5SWei Yongjun 
1224eacef4e2SWei Yongjun void test_loopcc(void)
1225eacef4e2SWei Yongjun {
1226eacef4e2SWei Yongjun 	struct regs inregs = { 0 }, outregs;
1227eacef4e2SWei Yongjun 
1228eacef4e2SWei Yongjun 	MK_INSN(loop, "mov $10, %ecx\n\t"
1229eacef4e2SWei Yongjun 		      "1: inc %eax\n\t"
1230eacef4e2SWei Yongjun 		      "loop 1b\n\t");
1231eacef4e2SWei Yongjun 
1232eacef4e2SWei Yongjun 	MK_INSN(loope, "mov $10, %ecx\n\t"
1233eacef4e2SWei Yongjun 		       "mov $1, %eax\n\t"
1234eacef4e2SWei Yongjun 		       "1: dec %eax\n\t"
1235eacef4e2SWei Yongjun 		       "loope 1b\n\t");
1236eacef4e2SWei Yongjun 
1237eacef4e2SWei Yongjun 	MK_INSN(loopne, "mov $10, %ecx\n\t"
1238eacef4e2SWei Yongjun 		        "mov $5, %eax\n\t"
1239eacef4e2SWei Yongjun 		        "1: dec %eax\n\t"
1240eacef4e2SWei Yongjun 			"loopne 1b\n\t");
1241eacef4e2SWei Yongjun 
1242eacef4e2SWei Yongjun 	exec_in_big_real_mode(&inregs, &outregs,
1243eacef4e2SWei Yongjun 			insn_loop, insn_loop_end - insn_loop);
1244eacef4e2SWei Yongjun 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 10)
1245eacef4e2SWei Yongjun 		print_serial("LOOPcc short Test 1: FAIL\n");
1246eacef4e2SWei Yongjun 	else
1247eacef4e2SWei Yongjun 		print_serial("LOOPcc short Test 1: PASS\n");
1248eacef4e2SWei Yongjun 
1249eacef4e2SWei Yongjun 	exec_in_big_real_mode(&inregs, &outregs,
1250eacef4e2SWei Yongjun 			insn_loope, insn_loope_end - insn_loope);
1251eacef4e2SWei Yongjun 	if(!regs_equal(&inregs, &outregs, R_AX | R_CX) ||
1252eacef4e2SWei Yongjun 	   outregs.eax != -1 || outregs.ecx != 8)
1253eacef4e2SWei Yongjun 		print_serial("LOOPcc short Test 2: FAIL\n");
1254eacef4e2SWei Yongjun 	else
1255eacef4e2SWei Yongjun 		print_serial("LOOPcc short Test 2: PASS\n");
1256eacef4e2SWei Yongjun 
1257eacef4e2SWei Yongjun 	exec_in_big_real_mode(&inregs, &outregs,
1258eacef4e2SWei Yongjun 			insn_loopne, insn_loopne_end - insn_loopne);
1259eacef4e2SWei Yongjun 	if(!regs_equal(&inregs, &outregs, R_AX | R_CX) ||
1260eacef4e2SWei Yongjun 	   outregs.eax != 0 || outregs.ecx != 5)
1261eacef4e2SWei Yongjun 		print_serial("LOOPcc short Test 3: FAIL\n");
1262eacef4e2SWei Yongjun 	else
1263eacef4e2SWei Yongjun 		print_serial("LOOPcc short Test 3: PASS\n");
1264eacef4e2SWei Yongjun }
1265eacef4e2SWei Yongjun 
1266b274feedSAvi Kivity static void test_das(void)
1267b274feedSAvi Kivity {
1268b274feedSAvi Kivity     struct regs inregs = { 0 }, outregs = { 0 };
1269b274feedSAvi Kivity     short i;
1270b274feedSAvi Kivity     static unsigned test_cases[1024] = {
1271b274feedSAvi Kivity         0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00,
1272b274feedSAvi Kivity         0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01,
1273b274feedSAvi Kivity         0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02,
1274b274feedSAvi Kivity         0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03,
1275b274feedSAvi Kivity         0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04,
1276b274feedSAvi Kivity         0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05,
1277b274feedSAvi Kivity         0x06000606, 0x8701a606, 0x56100006, 0x9711a006,
1278b274feedSAvi Kivity         0x02000707, 0x8301a707, 0x12100107, 0x9311a107,
1279b274feedSAvi Kivity         0x02000808, 0x8301a808, 0x12100208, 0x9311a208,
1280b274feedSAvi Kivity         0x06000909, 0x8701a909, 0x16100309, 0x9711a309,
1281b274feedSAvi Kivity         0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a,
1282b274feedSAvi Kivity         0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b,
1283b274feedSAvi Kivity         0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c,
1284b274feedSAvi Kivity         0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d,
1285b274feedSAvi Kivity         0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e,
1286b274feedSAvi Kivity         0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f,
1287b274feedSAvi Kivity         0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10,
1288b274feedSAvi Kivity         0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11,
1289b274feedSAvi Kivity         0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12,
1290b274feedSAvi Kivity         0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13,
1291b274feedSAvi Kivity         0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14,
1292b274feedSAvi Kivity         0x02001515, 0x8301b515, 0x16100f15, 0x9711af15,
1293b274feedSAvi Kivity         0x02001616, 0x8301b616, 0x12101016, 0x9311b016,
1294b274feedSAvi Kivity         0x06001717, 0x8701b717, 0x16101117, 0x9711b117,
1295b274feedSAvi Kivity         0x06001818, 0x8701b818, 0x16101218, 0x9711b218,
1296b274feedSAvi Kivity         0x02001919, 0x8301b919, 0x12101319, 0x9311b319,
1297b274feedSAvi Kivity         0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a,
1298b274feedSAvi Kivity         0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b,
1299b274feedSAvi Kivity         0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c,
1300b274feedSAvi Kivity         0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d,
1301b274feedSAvi Kivity         0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e,
1302b274feedSAvi Kivity         0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f,
1303b274feedSAvi Kivity         0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20,
1304b274feedSAvi Kivity         0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21,
1305b274feedSAvi Kivity         0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22,
1306b274feedSAvi Kivity         0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23,
1307b274feedSAvi Kivity         0x06002424, 0x8301c424, 0x16101e24, 0x9711be24,
1308b274feedSAvi Kivity         0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25,
1309b274feedSAvi Kivity         0x02002626, 0x8701c626, 0x12102026, 0x9711c026,
1310b274feedSAvi Kivity         0x06002727, 0x8301c727, 0x16102127, 0x9311c127,
1311b274feedSAvi Kivity         0x06002828, 0x8301c828, 0x16102228, 0x9311c228,
1312b274feedSAvi Kivity         0x02002929, 0x8701c929, 0x12102329, 0x9711c329,
1313b274feedSAvi Kivity         0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a,
1314b274feedSAvi Kivity         0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b,
1315b274feedSAvi Kivity         0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c,
1316b274feedSAvi Kivity         0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d,
1317b274feedSAvi Kivity         0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e,
1318b274feedSAvi Kivity         0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f,
1319b274feedSAvi Kivity         0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30,
1320b274feedSAvi Kivity         0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31,
1321b274feedSAvi Kivity         0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32,
1322b274feedSAvi Kivity         0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33,
1323b274feedSAvi Kivity         0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34,
1324b274feedSAvi Kivity         0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35,
1325b274feedSAvi Kivity         0x06003636, 0x8301d636, 0x16103036, 0x9311d036,
1326b274feedSAvi Kivity         0x02003737, 0x8701d737, 0x12103137, 0x9711d137,
1327b274feedSAvi Kivity         0x02003838, 0x8701d838, 0x12103238, 0x9711d238,
1328b274feedSAvi Kivity         0x06003939, 0x8301d939, 0x16103339, 0x9311d339,
1329b274feedSAvi Kivity         0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a,
1330b274feedSAvi Kivity         0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b,
1331b274feedSAvi Kivity         0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c,
1332b274feedSAvi Kivity         0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d,
1333b274feedSAvi Kivity         0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e,
1334b274feedSAvi Kivity         0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f,
1335b274feedSAvi Kivity         0x02004040, 0x8301e040, 0x16103a40, 0x9311da40,
1336b274feedSAvi Kivity         0x06004141, 0x8701e141, 0x12103b41, 0x9711db41,
1337b274feedSAvi Kivity         0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42,
1338b274feedSAvi Kivity         0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43,
1339b274feedSAvi Kivity         0x06004444, 0x8701e444, 0x12103e44, 0x9711de44,
1340b274feedSAvi Kivity         0x02004545, 0x8301e545, 0x16103f45, 0x9311df45,
1341b274feedSAvi Kivity         0x02004646, 0x8301e646, 0x12104046, 0x9311e046,
1342b274feedSAvi Kivity         0x06004747, 0x8701e747, 0x16104147, 0x9711e147,
1343b274feedSAvi Kivity         0x06004848, 0x8701e848, 0x16104248, 0x9711e248,
1344b274feedSAvi Kivity         0x02004949, 0x8301e949, 0x12104349, 0x9311e349,
1345b274feedSAvi Kivity         0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a,
1346b274feedSAvi Kivity         0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b,
1347b274feedSAvi Kivity         0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c,
1348b274feedSAvi Kivity         0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d,
1349b274feedSAvi Kivity         0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e,
1350b274feedSAvi Kivity         0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f,
1351b274feedSAvi Kivity         0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50,
1352b274feedSAvi Kivity         0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51,
1353b274feedSAvi Kivity         0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52,
1354b274feedSAvi Kivity         0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53,
1355b274feedSAvi Kivity         0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54,
1356b274feedSAvi Kivity         0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55,
1357b274feedSAvi Kivity         0x06005656, 0x8701f656, 0x16105056, 0x9711f056,
1358b274feedSAvi Kivity         0x02005757, 0x8301f757, 0x12105157, 0x9311f157,
1359b274feedSAvi Kivity         0x02005858, 0x8301f858, 0x12105258, 0x9311f258,
1360b274feedSAvi Kivity         0x06005959, 0x8701f959, 0x16105359, 0x9711f359,
1361b274feedSAvi Kivity         0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a,
1362b274feedSAvi Kivity         0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b,
1363b274feedSAvi Kivity         0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c,
1364b274feedSAvi Kivity         0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d,
1365b274feedSAvi Kivity         0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e,
1366b274feedSAvi Kivity         0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f,
1367b274feedSAvi Kivity         0x06006060, 0x47010060, 0x16105a60, 0x9711fa60,
1368b274feedSAvi Kivity         0x02006161, 0x03010161, 0x12105b61, 0x9311fb61,
1369b274feedSAvi Kivity         0x02006262, 0x03010262, 0x16105c62, 0x9711fc62,
1370b274feedSAvi Kivity         0x06006363, 0x07010363, 0x12105d63, 0x9311fd63,
1371b274feedSAvi Kivity         0x02006464, 0x03010464, 0x12105e64, 0x9311fe64,
1372b274feedSAvi Kivity         0x06006565, 0x07010565, 0x16105f65, 0x9711ff65,
1373b274feedSAvi Kivity         0x06006666, 0x07010666, 0x16106066, 0x57110066,
1374b274feedSAvi Kivity         0x02006767, 0x03010767, 0x12106167, 0x13110167,
1375b274feedSAvi Kivity         0x02006868, 0x03010868, 0x12106268, 0x13110268,
1376b274feedSAvi Kivity         0x06006969, 0x07010969, 0x16106369, 0x17110369,
1377b274feedSAvi Kivity         0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a,
1378b274feedSAvi Kivity         0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b,
1379b274feedSAvi Kivity         0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c,
1380b274feedSAvi Kivity         0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d,
1381b274feedSAvi Kivity         0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e,
1382b274feedSAvi Kivity         0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f,
1383b274feedSAvi Kivity         0x02007070, 0x03011070, 0x16106a70, 0x17110a70,
1384b274feedSAvi Kivity         0x06007171, 0x07011171, 0x12106b71, 0x13110b71,
1385b274feedSAvi Kivity         0x06007272, 0x07011272, 0x16106c72, 0x17110c72,
1386b274feedSAvi Kivity         0x02007373, 0x03011373, 0x12106d73, 0x13110d73,
1387b274feedSAvi Kivity         0x06007474, 0x07011474, 0x12106e74, 0x13110e74,
1388b274feedSAvi Kivity         0x02007575, 0x03011575, 0x16106f75, 0x17110f75,
1389b274feedSAvi Kivity         0x02007676, 0x03011676, 0x12107076, 0x13111076,
1390b274feedSAvi Kivity         0x06007777, 0x07011777, 0x16107177, 0x17111177,
1391b274feedSAvi Kivity         0x06007878, 0x07011878, 0x16107278, 0x17111278,
1392b274feedSAvi Kivity         0x02007979, 0x03011979, 0x12107379, 0x13111379,
1393b274feedSAvi Kivity         0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a,
1394b274feedSAvi Kivity         0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b,
1395b274feedSAvi Kivity         0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c,
1396b274feedSAvi Kivity         0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d,
1397b274feedSAvi Kivity         0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e,
1398b274feedSAvi Kivity         0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f,
1399b274feedSAvi Kivity         0x82008080, 0x03012080, 0x12107a80, 0x13111a80,
1400b274feedSAvi Kivity         0x86008181, 0x07012181, 0x16107b81, 0x17111b81,
1401b274feedSAvi Kivity         0x86008282, 0x07012282, 0x12107c82, 0x13111c82,
1402b274feedSAvi Kivity         0x82008383, 0x03012383, 0x16107d83, 0x17111d83,
1403b274feedSAvi Kivity         0x86008484, 0x07012484, 0x16107e84, 0x17111e84,
1404b274feedSAvi Kivity         0x82008585, 0x03012585, 0x12107f85, 0x13111f85,
1405b274feedSAvi Kivity         0x82008686, 0x03012686, 0x92108086, 0x13112086,
1406b274feedSAvi Kivity         0x86008787, 0x07012787, 0x96108187, 0x17112187,
1407b274feedSAvi Kivity         0x86008888, 0x07012888, 0x96108288, 0x17112288,
1408b274feedSAvi Kivity         0x82008989, 0x03012989, 0x92108389, 0x13112389,
1409b274feedSAvi Kivity         0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a,
1410b274feedSAvi Kivity         0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b,
1411b274feedSAvi Kivity         0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c,
1412b274feedSAvi Kivity         0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d,
1413b274feedSAvi Kivity         0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e,
1414b274feedSAvi Kivity         0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f,
1415b274feedSAvi Kivity         0x86009090, 0x07013090, 0x92108a90, 0x13112a90,
1416b274feedSAvi Kivity         0x82009191, 0x03013191, 0x96108b91, 0x17112b91,
1417b274feedSAvi Kivity         0x82009292, 0x03013292, 0x92108c92, 0x13112c92,
1418b274feedSAvi Kivity         0x86009393, 0x07013393, 0x96108d93, 0x17112d93,
1419b274feedSAvi Kivity         0x82009494, 0x03013494, 0x96108e94, 0x17112e94,
1420b274feedSAvi Kivity         0x86009595, 0x07013595, 0x92108f95, 0x13112f95,
1421b274feedSAvi Kivity         0x86009696, 0x07013696, 0x96109096, 0x17113096,
1422b274feedSAvi Kivity         0x82009797, 0x03013797, 0x92109197, 0x13113197,
1423b274feedSAvi Kivity         0x82009898, 0x03013898, 0x92109298, 0x13113298,
1424b274feedSAvi Kivity         0x86009999, 0x07013999, 0x96109399, 0x17113399,
1425b274feedSAvi Kivity         0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a,
1426b274feedSAvi Kivity         0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b,
1427b274feedSAvi Kivity         0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c,
1428b274feedSAvi Kivity         0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d,
1429b274feedSAvi Kivity         0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e,
1430b274feedSAvi Kivity         0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f,
1431b274feedSAvi Kivity         0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0,
1432b274feedSAvi Kivity         0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1,
1433b274feedSAvi Kivity         0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2,
1434b274feedSAvi Kivity         0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3,
1435b274feedSAvi Kivity         0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4,
1436b274feedSAvi Kivity         0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5,
1437b274feedSAvi Kivity         0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6,
1438b274feedSAvi Kivity         0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7,
1439b274feedSAvi Kivity         0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8,
1440b274feedSAvi Kivity         0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9,
1441b274feedSAvi Kivity         0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa,
1442b274feedSAvi Kivity         0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab,
1443b274feedSAvi Kivity         0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac,
1444b274feedSAvi Kivity         0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad,
1445b274feedSAvi Kivity         0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae,
1446b274feedSAvi Kivity         0x130049af, 0x130149af, 0x131049af, 0x131149af,
1447b274feedSAvi Kivity         0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0,
1448b274feedSAvi Kivity         0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1,
1449b274feedSAvi Kivity         0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2,
1450b274feedSAvi Kivity         0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3,
1451b274feedSAvi Kivity         0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4,
1452b274feedSAvi Kivity         0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5,
1453b274feedSAvi Kivity         0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6,
1454b274feedSAvi Kivity         0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7,
1455b274feedSAvi Kivity         0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8,
1456b274feedSAvi Kivity         0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9,
1457b274feedSAvi Kivity         0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba,
1458b274feedSAvi Kivity         0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb,
1459b274feedSAvi Kivity         0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc,
1460b274feedSAvi Kivity         0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd,
1461b274feedSAvi Kivity         0x130058be, 0x130158be, 0x131058be, 0x131158be,
1462b274feedSAvi Kivity         0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf,
1463b274feedSAvi Kivity         0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0,
1464b274feedSAvi Kivity         0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1,
1465b274feedSAvi Kivity         0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2,
1466b274feedSAvi Kivity         0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3,
1467b274feedSAvi Kivity         0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4,
1468b274feedSAvi Kivity         0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5,
1469b274feedSAvi Kivity         0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6,
1470b274feedSAvi Kivity         0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7,
1471b274feedSAvi Kivity         0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8,
1472b274feedSAvi Kivity         0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9,
1473b274feedSAvi Kivity         0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca,
1474b274feedSAvi Kivity         0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb,
1475b274feedSAvi Kivity         0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc,
1476b274feedSAvi Kivity         0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd,
1477b274feedSAvi Kivity         0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce,
1478b274feedSAvi Kivity         0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf,
1479b274feedSAvi Kivity         0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0,
1480b274feedSAvi Kivity         0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1,
1481b274feedSAvi Kivity         0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2,
1482b274feedSAvi Kivity         0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3,
1483b274feedSAvi Kivity         0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4,
1484b274feedSAvi Kivity         0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5,
1485b274feedSAvi Kivity         0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6,
1486b274feedSAvi Kivity         0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7,
1487b274feedSAvi Kivity         0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8,
1488b274feedSAvi Kivity         0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9,
1489b274feedSAvi Kivity         0x170074da, 0x170174da, 0x171074da, 0x171174da,
1490b274feedSAvi Kivity         0x130075db, 0x130175db, 0x131075db, 0x131175db,
1491b274feedSAvi Kivity         0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc,
1492b274feedSAvi Kivity         0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd,
1493b274feedSAvi Kivity         0x170078de, 0x170178de, 0x171078de, 0x171178de,
1494b274feedSAvi Kivity         0x130079df, 0x130179df, 0x131079df, 0x131179df,
1495b274feedSAvi Kivity         0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0,
1496b274feedSAvi Kivity         0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1,
1497b274feedSAvi Kivity         0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2,
1498b274feedSAvi Kivity         0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3,
1499b274feedSAvi Kivity         0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4,
1500b274feedSAvi Kivity         0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5,
1501b274feedSAvi Kivity         0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6,
1502b274feedSAvi Kivity         0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7,
1503b274feedSAvi Kivity         0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8,
1504b274feedSAvi Kivity         0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9,
1505b274feedSAvi Kivity         0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea,
1506b274feedSAvi Kivity         0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb,
1507b274feedSAvi Kivity         0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec,
1508b274feedSAvi Kivity         0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed,
1509b274feedSAvi Kivity         0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee,
1510b274feedSAvi Kivity         0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef,
1511b274feedSAvi Kivity         0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0,
1512b274feedSAvi Kivity         0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1,
1513b274feedSAvi Kivity         0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2,
1514b274feedSAvi Kivity         0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3,
1515b274feedSAvi Kivity         0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4,
1516b274feedSAvi Kivity         0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5,
1517b274feedSAvi Kivity         0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6,
1518b274feedSAvi Kivity         0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7,
1519b274feedSAvi Kivity         0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8,
1520b274feedSAvi Kivity         0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9,
1521b274feedSAvi Kivity         0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa,
1522b274feedSAvi Kivity         0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb,
1523b274feedSAvi Kivity         0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc,
1524b274feedSAvi Kivity         0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd,
1525b274feedSAvi Kivity         0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe,
1526b274feedSAvi Kivity         0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff,
1527b274feedSAvi Kivity     };
1528b274feedSAvi Kivity 
1529b274feedSAvi Kivity     MK_INSN(das, "das");
1530b274feedSAvi Kivity 
1531b274feedSAvi Kivity     for (i = 0; i < 1024; ++i) {
1532b274feedSAvi Kivity         unsigned tmp = test_cases[i];
1533b274feedSAvi Kivity         inregs.eax = tmp & 0xff;
1534b274feedSAvi Kivity         inregs.eflags = (tmp >> 16) & 0xff;
1535b274feedSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
1536b274feedSAvi Kivity 			      insn_das,
1537b274feedSAvi Kivity 			      insn_das_end - insn_das);
1538b274feedSAvi Kivity 
1539b274feedSAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX)
1540b274feedSAvi Kivity             || outregs.eax != ((tmp >> 8) & 0xff)
1541b274feedSAvi Kivity             || (outregs.eflags & 0xff) != (tmp >> 24)) {
1542b274feedSAvi Kivity 		print_serial("DAS Test: FAIL\n");
1543b274feedSAvi Kivity                 return;
1544b274feedSAvi Kivity         }
1545b274feedSAvi Kivity     }
1546b274feedSAvi Kivity     print_serial("DAS Test: PASS\n");
1547b274feedSAvi Kivity }
1548b274feedSAvi Kivity 
1549*0cbd5b06SMohammed Gamal void test_cwd_cdq()
1550*0cbd5b06SMohammed Gamal {
1551*0cbd5b06SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
1552*0cbd5b06SMohammed Gamal 
1553*0cbd5b06SMohammed Gamal 	/* Sign-bit set */
1554*0cbd5b06SMohammed Gamal 	MK_INSN(cwd_1, "mov $0x8000, %ax\n\t"
1555*0cbd5b06SMohammed Gamal 		       "cwd\n\t");
1556*0cbd5b06SMohammed Gamal 
1557*0cbd5b06SMohammed Gamal 	/* Sign-bit not set */
1558*0cbd5b06SMohammed Gamal 	MK_INSN(cwd_2, "mov $0x1000, %ax\n\t"
1559*0cbd5b06SMohammed Gamal 		       "cwd\n\t");
1560*0cbd5b06SMohammed Gamal 
1561*0cbd5b06SMohammed Gamal 	/* Sign-bit set */
1562*0cbd5b06SMohammed Gamal 	MK_INSN(cdq_1, "mov $0x80000000, %eax\n\t"
1563*0cbd5b06SMohammed Gamal 		       "cdq\n\t");
1564*0cbd5b06SMohammed Gamal 
1565*0cbd5b06SMohammed Gamal 	/* Sign-bit not set */
1566*0cbd5b06SMohammed Gamal 	MK_INSN(cdq_2, "mov $0x10000000, %eax\n\t"
1567*0cbd5b06SMohammed Gamal 		       "cdq\n\t");
1568*0cbd5b06SMohammed Gamal 
1569*0cbd5b06SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1570*0cbd5b06SMohammed Gamal 			      insn_cwd_1,
1571*0cbd5b06SMohammed Gamal 			      insn_cwd_1_end - insn_cwd_1);
1572*0cbd5b06SMohammed Gamal 
1573*0cbd5b06SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || outregs.eax != 0x8000 || outregs.edx != 0xffff)
1574*0cbd5b06SMohammed Gamal 		print_serial("cwd Test 1: FAIL\n");
1575*0cbd5b06SMohammed Gamal 	else
1576*0cbd5b06SMohammed Gamal 		print_serial("cwd Test 1: PASS\n");
1577*0cbd5b06SMohammed Gamal 
1578*0cbd5b06SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1579*0cbd5b06SMohammed Gamal 			      insn_cwd_2,
1580*0cbd5b06SMohammed Gamal 			      insn_cwd_2_end - insn_cwd_2);
1581*0cbd5b06SMohammed Gamal 
1582*0cbd5b06SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || outregs.eax != 0x1000 || outregs.edx != 0)
1583*0cbd5b06SMohammed Gamal 		print_serial("cwd Test 2: FAIL\n");
1584*0cbd5b06SMohammed Gamal 	else
1585*0cbd5b06SMohammed Gamal 		print_serial("cwd Test 2: PASS\n");
1586*0cbd5b06SMohammed Gamal 
1587*0cbd5b06SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1588*0cbd5b06SMohammed Gamal 			      insn_cdq_1,
1589*0cbd5b06SMohammed Gamal 			      insn_cdq_1_end - insn_cdq_1);
1590*0cbd5b06SMohammed Gamal 
1591*0cbd5b06SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || outregs.eax != 0x80000000 || outregs.edx != 0xffffffff)
1592*0cbd5b06SMohammed Gamal 		print_serial("cdq Test 1: FAIL\n");
1593*0cbd5b06SMohammed Gamal 	else
1594*0cbd5b06SMohammed Gamal 		print_serial("cdq Test 1: PASS\n");
1595*0cbd5b06SMohammed Gamal 
1596*0cbd5b06SMohammed Gamal 	exec_in_big_real_mode(&inregs, &outregs,
1597*0cbd5b06SMohammed Gamal 			      insn_cdq_2,
1598*0cbd5b06SMohammed Gamal 			      insn_cdq_2_end - insn_cdq_2);
1599*0cbd5b06SMohammed Gamal 
1600*0cbd5b06SMohammed Gamal 	if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || outregs.eax != 0x10000000 || outregs.edx != 0)
1601*0cbd5b06SMohammed Gamal 		print_serial("cdq Test 2: FAIL\n");
1602*0cbd5b06SMohammed Gamal 	else
1603*0cbd5b06SMohammed Gamal 		print_serial("cdq Test 2: PASS\n");
1604*0cbd5b06SMohammed Gamal }
1605*0cbd5b06SMohammed Gamal 
16067d36db35SAvi Kivity void realmode_start(void)
16077d36db35SAvi Kivity {
16087d36db35SAvi Kivity 	test_null();
16097d36db35SAvi Kivity 
16107d36db35SAvi Kivity 	test_shld();
16117d36db35SAvi Kivity 	test_push_pop();
16127d36db35SAvi Kivity 	test_pusha_popa();
16137d36db35SAvi Kivity 	test_mov_imm();
16147d36db35SAvi Kivity 	test_cmp_imm();
16157d36db35SAvi Kivity 	test_add_imm();
16167d36db35SAvi Kivity 	test_sub_imm();
16177d36db35SAvi Kivity 	test_xor_imm();
16187d36db35SAvi Kivity 	test_io();
16197d36db35SAvi Kivity 	test_eflags_insn();
16207d36db35SAvi Kivity 	test_jcc_short();
16217d36db35SAvi Kivity 	test_jcc_near();
16227d36db35SAvi Kivity 	/* test_call() uses short jump so call it after testing jcc */
16237d36db35SAvi Kivity 	test_call();
16247d36db35SAvi Kivity 	/* long jmp test uses call near so test it after testing call */
16257d36db35SAvi Kivity 	test_long_jmp();
16267d36db35SAvi Kivity 	test_xchg();
16277d36db35SAvi Kivity 	test_iret();
162896b9ca1eSMohammed Gamal 	test_int();
1629fa74f8a6SMohammed Gamal 	test_imul();
163059317bd1SMohammed Gamal 	test_mul();
16310d4c7614SMohammed Gamal 	test_div();
16320d4c7614SMohammed Gamal 	test_idiv();
1633eacef4e2SWei Yongjun 	test_loopcc();
16346e293cf5SWei Yongjun 	test_cbw();
1635*0cbd5b06SMohammed Gamal 	test_cwd_cdq();
1636b274feedSAvi Kivity 	test_das();
16377d36db35SAvi Kivity 
16387d36db35SAvi Kivity 	exit(0);
16397d36db35SAvi Kivity }
16407d36db35SAvi Kivity 
16417d36db35SAvi Kivity unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff };
16427d36db35SAvi Kivity 
16437d36db35SAvi Kivity struct __attribute__((packed)) {
16447d36db35SAvi Kivity 	unsigned short limit;
16457d36db35SAvi Kivity 	void *base;
16467d36db35SAvi Kivity } r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt };
16477d36db35SAvi Kivity 
16487d36db35SAvi Kivity asm(
16497d36db35SAvi Kivity 	".section .init \n\t"
16507d36db35SAvi Kivity 
16517d36db35SAvi Kivity 	".code32 \n\t"
16527d36db35SAvi Kivity 
16537d36db35SAvi Kivity 	"mb_magic = 0x1BADB002 \n\t"
16547d36db35SAvi Kivity 	"mb_flags = 0x0 \n\t"
16557d36db35SAvi Kivity 
16567d36db35SAvi Kivity 	"# multiboot header \n\t"
16577d36db35SAvi Kivity 	".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t"
16587d36db35SAvi Kivity 
16597d36db35SAvi Kivity 	".globl start \n\t"
16607d36db35SAvi Kivity 	".data \n\t"
16617d36db35SAvi Kivity 	". = . + 4096 \n\t"
16627d36db35SAvi Kivity 	"stacktop: \n\t"
16637d36db35SAvi Kivity 
16647d36db35SAvi Kivity 	".text \n\t"
16657d36db35SAvi Kivity 	"start: \n\t"
16667d36db35SAvi Kivity 	"lgdt r_gdt_descr \n\t"
16677d36db35SAvi Kivity 	"ljmp $8, $1f; 1: \n\t"
16687d36db35SAvi Kivity 	".code16gcc \n\t"
16697d36db35SAvi Kivity 	"mov $16, %eax \n\t"
16707d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
16717d36db35SAvi Kivity 	"mov %ax, %es \n\t"
16727d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
16737d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
16747d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
16757d36db35SAvi Kivity 	"mov %cr0, %eax \n\t"
16767d36db35SAvi Kivity 	"btc $0, %eax \n\t"
16777d36db35SAvi Kivity 	"mov %eax, %cr0 \n\t"
16787d36db35SAvi Kivity 	"ljmp $0, $realmode_entry \n\t"
16797d36db35SAvi Kivity 
16807d36db35SAvi Kivity 	"realmode_entry: \n\t"
16817d36db35SAvi Kivity 
16827d36db35SAvi Kivity 	"xor %ax, %ax \n\t"
16837d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
16847d36db35SAvi Kivity 	"mov %ax, %es \n\t"
16857d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
16867d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
16877d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
16887d36db35SAvi Kivity 	"mov $stacktop, %esp\n\t"
16897d36db35SAvi Kivity 	"ljmp $0, $realmode_start \n\t"
16907d36db35SAvi Kivity 
16917d36db35SAvi Kivity 	".code16gcc \n\t"
16927d36db35SAvi Kivity 	);
1693