xref: /kvm-unit-tests/x86/realmode.c (revision b274feed8adb0f7e4d951dcb2ae84276f7cf5774)
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 
1266*b274feedSAvi Kivity static void test_das(void)
1267*b274feedSAvi Kivity {
1268*b274feedSAvi Kivity     struct regs inregs = { 0 }, outregs = { 0 };
1269*b274feedSAvi Kivity     short i;
1270*b274feedSAvi Kivity     static unsigned test_cases[1024] = {
1271*b274feedSAvi Kivity         0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00,
1272*b274feedSAvi Kivity         0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01,
1273*b274feedSAvi Kivity         0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02,
1274*b274feedSAvi Kivity         0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03,
1275*b274feedSAvi Kivity         0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04,
1276*b274feedSAvi Kivity         0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05,
1277*b274feedSAvi Kivity         0x06000606, 0x8701a606, 0x56100006, 0x9711a006,
1278*b274feedSAvi Kivity         0x02000707, 0x8301a707, 0x12100107, 0x9311a107,
1279*b274feedSAvi Kivity         0x02000808, 0x8301a808, 0x12100208, 0x9311a208,
1280*b274feedSAvi Kivity         0x06000909, 0x8701a909, 0x16100309, 0x9711a309,
1281*b274feedSAvi Kivity         0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a,
1282*b274feedSAvi Kivity         0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b,
1283*b274feedSAvi Kivity         0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c,
1284*b274feedSAvi Kivity         0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d,
1285*b274feedSAvi Kivity         0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e,
1286*b274feedSAvi Kivity         0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f,
1287*b274feedSAvi Kivity         0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10,
1288*b274feedSAvi Kivity         0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11,
1289*b274feedSAvi Kivity         0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12,
1290*b274feedSAvi Kivity         0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13,
1291*b274feedSAvi Kivity         0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14,
1292*b274feedSAvi Kivity         0x02001515, 0x8301b515, 0x16100f15, 0x9711af15,
1293*b274feedSAvi Kivity         0x02001616, 0x8301b616, 0x12101016, 0x9311b016,
1294*b274feedSAvi Kivity         0x06001717, 0x8701b717, 0x16101117, 0x9711b117,
1295*b274feedSAvi Kivity         0x06001818, 0x8701b818, 0x16101218, 0x9711b218,
1296*b274feedSAvi Kivity         0x02001919, 0x8301b919, 0x12101319, 0x9311b319,
1297*b274feedSAvi Kivity         0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a,
1298*b274feedSAvi Kivity         0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b,
1299*b274feedSAvi Kivity         0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c,
1300*b274feedSAvi Kivity         0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d,
1301*b274feedSAvi Kivity         0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e,
1302*b274feedSAvi Kivity         0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f,
1303*b274feedSAvi Kivity         0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20,
1304*b274feedSAvi Kivity         0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21,
1305*b274feedSAvi Kivity         0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22,
1306*b274feedSAvi Kivity         0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23,
1307*b274feedSAvi Kivity         0x06002424, 0x8301c424, 0x16101e24, 0x9711be24,
1308*b274feedSAvi Kivity         0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25,
1309*b274feedSAvi Kivity         0x02002626, 0x8701c626, 0x12102026, 0x9711c026,
1310*b274feedSAvi Kivity         0x06002727, 0x8301c727, 0x16102127, 0x9311c127,
1311*b274feedSAvi Kivity         0x06002828, 0x8301c828, 0x16102228, 0x9311c228,
1312*b274feedSAvi Kivity         0x02002929, 0x8701c929, 0x12102329, 0x9711c329,
1313*b274feedSAvi Kivity         0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a,
1314*b274feedSAvi Kivity         0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b,
1315*b274feedSAvi Kivity         0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c,
1316*b274feedSAvi Kivity         0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d,
1317*b274feedSAvi Kivity         0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e,
1318*b274feedSAvi Kivity         0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f,
1319*b274feedSAvi Kivity         0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30,
1320*b274feedSAvi Kivity         0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31,
1321*b274feedSAvi Kivity         0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32,
1322*b274feedSAvi Kivity         0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33,
1323*b274feedSAvi Kivity         0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34,
1324*b274feedSAvi Kivity         0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35,
1325*b274feedSAvi Kivity         0x06003636, 0x8301d636, 0x16103036, 0x9311d036,
1326*b274feedSAvi Kivity         0x02003737, 0x8701d737, 0x12103137, 0x9711d137,
1327*b274feedSAvi Kivity         0x02003838, 0x8701d838, 0x12103238, 0x9711d238,
1328*b274feedSAvi Kivity         0x06003939, 0x8301d939, 0x16103339, 0x9311d339,
1329*b274feedSAvi Kivity         0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a,
1330*b274feedSAvi Kivity         0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b,
1331*b274feedSAvi Kivity         0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c,
1332*b274feedSAvi Kivity         0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d,
1333*b274feedSAvi Kivity         0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e,
1334*b274feedSAvi Kivity         0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f,
1335*b274feedSAvi Kivity         0x02004040, 0x8301e040, 0x16103a40, 0x9311da40,
1336*b274feedSAvi Kivity         0x06004141, 0x8701e141, 0x12103b41, 0x9711db41,
1337*b274feedSAvi Kivity         0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42,
1338*b274feedSAvi Kivity         0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43,
1339*b274feedSAvi Kivity         0x06004444, 0x8701e444, 0x12103e44, 0x9711de44,
1340*b274feedSAvi Kivity         0x02004545, 0x8301e545, 0x16103f45, 0x9311df45,
1341*b274feedSAvi Kivity         0x02004646, 0x8301e646, 0x12104046, 0x9311e046,
1342*b274feedSAvi Kivity         0x06004747, 0x8701e747, 0x16104147, 0x9711e147,
1343*b274feedSAvi Kivity         0x06004848, 0x8701e848, 0x16104248, 0x9711e248,
1344*b274feedSAvi Kivity         0x02004949, 0x8301e949, 0x12104349, 0x9311e349,
1345*b274feedSAvi Kivity         0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a,
1346*b274feedSAvi Kivity         0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b,
1347*b274feedSAvi Kivity         0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c,
1348*b274feedSAvi Kivity         0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d,
1349*b274feedSAvi Kivity         0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e,
1350*b274feedSAvi Kivity         0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f,
1351*b274feedSAvi Kivity         0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50,
1352*b274feedSAvi Kivity         0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51,
1353*b274feedSAvi Kivity         0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52,
1354*b274feedSAvi Kivity         0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53,
1355*b274feedSAvi Kivity         0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54,
1356*b274feedSAvi Kivity         0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55,
1357*b274feedSAvi Kivity         0x06005656, 0x8701f656, 0x16105056, 0x9711f056,
1358*b274feedSAvi Kivity         0x02005757, 0x8301f757, 0x12105157, 0x9311f157,
1359*b274feedSAvi Kivity         0x02005858, 0x8301f858, 0x12105258, 0x9311f258,
1360*b274feedSAvi Kivity         0x06005959, 0x8701f959, 0x16105359, 0x9711f359,
1361*b274feedSAvi Kivity         0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a,
1362*b274feedSAvi Kivity         0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b,
1363*b274feedSAvi Kivity         0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c,
1364*b274feedSAvi Kivity         0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d,
1365*b274feedSAvi Kivity         0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e,
1366*b274feedSAvi Kivity         0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f,
1367*b274feedSAvi Kivity         0x06006060, 0x47010060, 0x16105a60, 0x9711fa60,
1368*b274feedSAvi Kivity         0x02006161, 0x03010161, 0x12105b61, 0x9311fb61,
1369*b274feedSAvi Kivity         0x02006262, 0x03010262, 0x16105c62, 0x9711fc62,
1370*b274feedSAvi Kivity         0x06006363, 0x07010363, 0x12105d63, 0x9311fd63,
1371*b274feedSAvi Kivity         0x02006464, 0x03010464, 0x12105e64, 0x9311fe64,
1372*b274feedSAvi Kivity         0x06006565, 0x07010565, 0x16105f65, 0x9711ff65,
1373*b274feedSAvi Kivity         0x06006666, 0x07010666, 0x16106066, 0x57110066,
1374*b274feedSAvi Kivity         0x02006767, 0x03010767, 0x12106167, 0x13110167,
1375*b274feedSAvi Kivity         0x02006868, 0x03010868, 0x12106268, 0x13110268,
1376*b274feedSAvi Kivity         0x06006969, 0x07010969, 0x16106369, 0x17110369,
1377*b274feedSAvi Kivity         0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a,
1378*b274feedSAvi Kivity         0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b,
1379*b274feedSAvi Kivity         0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c,
1380*b274feedSAvi Kivity         0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d,
1381*b274feedSAvi Kivity         0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e,
1382*b274feedSAvi Kivity         0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f,
1383*b274feedSAvi Kivity         0x02007070, 0x03011070, 0x16106a70, 0x17110a70,
1384*b274feedSAvi Kivity         0x06007171, 0x07011171, 0x12106b71, 0x13110b71,
1385*b274feedSAvi Kivity         0x06007272, 0x07011272, 0x16106c72, 0x17110c72,
1386*b274feedSAvi Kivity         0x02007373, 0x03011373, 0x12106d73, 0x13110d73,
1387*b274feedSAvi Kivity         0x06007474, 0x07011474, 0x12106e74, 0x13110e74,
1388*b274feedSAvi Kivity         0x02007575, 0x03011575, 0x16106f75, 0x17110f75,
1389*b274feedSAvi Kivity         0x02007676, 0x03011676, 0x12107076, 0x13111076,
1390*b274feedSAvi Kivity         0x06007777, 0x07011777, 0x16107177, 0x17111177,
1391*b274feedSAvi Kivity         0x06007878, 0x07011878, 0x16107278, 0x17111278,
1392*b274feedSAvi Kivity         0x02007979, 0x03011979, 0x12107379, 0x13111379,
1393*b274feedSAvi Kivity         0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a,
1394*b274feedSAvi Kivity         0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b,
1395*b274feedSAvi Kivity         0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c,
1396*b274feedSAvi Kivity         0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d,
1397*b274feedSAvi Kivity         0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e,
1398*b274feedSAvi Kivity         0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f,
1399*b274feedSAvi Kivity         0x82008080, 0x03012080, 0x12107a80, 0x13111a80,
1400*b274feedSAvi Kivity         0x86008181, 0x07012181, 0x16107b81, 0x17111b81,
1401*b274feedSAvi Kivity         0x86008282, 0x07012282, 0x12107c82, 0x13111c82,
1402*b274feedSAvi Kivity         0x82008383, 0x03012383, 0x16107d83, 0x17111d83,
1403*b274feedSAvi Kivity         0x86008484, 0x07012484, 0x16107e84, 0x17111e84,
1404*b274feedSAvi Kivity         0x82008585, 0x03012585, 0x12107f85, 0x13111f85,
1405*b274feedSAvi Kivity         0x82008686, 0x03012686, 0x92108086, 0x13112086,
1406*b274feedSAvi Kivity         0x86008787, 0x07012787, 0x96108187, 0x17112187,
1407*b274feedSAvi Kivity         0x86008888, 0x07012888, 0x96108288, 0x17112288,
1408*b274feedSAvi Kivity         0x82008989, 0x03012989, 0x92108389, 0x13112389,
1409*b274feedSAvi Kivity         0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a,
1410*b274feedSAvi Kivity         0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b,
1411*b274feedSAvi Kivity         0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c,
1412*b274feedSAvi Kivity         0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d,
1413*b274feedSAvi Kivity         0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e,
1414*b274feedSAvi Kivity         0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f,
1415*b274feedSAvi Kivity         0x86009090, 0x07013090, 0x92108a90, 0x13112a90,
1416*b274feedSAvi Kivity         0x82009191, 0x03013191, 0x96108b91, 0x17112b91,
1417*b274feedSAvi Kivity         0x82009292, 0x03013292, 0x92108c92, 0x13112c92,
1418*b274feedSAvi Kivity         0x86009393, 0x07013393, 0x96108d93, 0x17112d93,
1419*b274feedSAvi Kivity         0x82009494, 0x03013494, 0x96108e94, 0x17112e94,
1420*b274feedSAvi Kivity         0x86009595, 0x07013595, 0x92108f95, 0x13112f95,
1421*b274feedSAvi Kivity         0x86009696, 0x07013696, 0x96109096, 0x17113096,
1422*b274feedSAvi Kivity         0x82009797, 0x03013797, 0x92109197, 0x13113197,
1423*b274feedSAvi Kivity         0x82009898, 0x03013898, 0x92109298, 0x13113298,
1424*b274feedSAvi Kivity         0x86009999, 0x07013999, 0x96109399, 0x17113399,
1425*b274feedSAvi Kivity         0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a,
1426*b274feedSAvi Kivity         0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b,
1427*b274feedSAvi Kivity         0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c,
1428*b274feedSAvi Kivity         0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d,
1429*b274feedSAvi Kivity         0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e,
1430*b274feedSAvi Kivity         0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f,
1431*b274feedSAvi Kivity         0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0,
1432*b274feedSAvi Kivity         0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1,
1433*b274feedSAvi Kivity         0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2,
1434*b274feedSAvi Kivity         0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3,
1435*b274feedSAvi Kivity         0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4,
1436*b274feedSAvi Kivity         0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5,
1437*b274feedSAvi Kivity         0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6,
1438*b274feedSAvi Kivity         0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7,
1439*b274feedSAvi Kivity         0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8,
1440*b274feedSAvi Kivity         0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9,
1441*b274feedSAvi Kivity         0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa,
1442*b274feedSAvi Kivity         0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab,
1443*b274feedSAvi Kivity         0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac,
1444*b274feedSAvi Kivity         0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad,
1445*b274feedSAvi Kivity         0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae,
1446*b274feedSAvi Kivity         0x130049af, 0x130149af, 0x131049af, 0x131149af,
1447*b274feedSAvi Kivity         0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0,
1448*b274feedSAvi Kivity         0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1,
1449*b274feedSAvi Kivity         0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2,
1450*b274feedSAvi Kivity         0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3,
1451*b274feedSAvi Kivity         0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4,
1452*b274feedSAvi Kivity         0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5,
1453*b274feedSAvi Kivity         0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6,
1454*b274feedSAvi Kivity         0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7,
1455*b274feedSAvi Kivity         0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8,
1456*b274feedSAvi Kivity         0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9,
1457*b274feedSAvi Kivity         0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba,
1458*b274feedSAvi Kivity         0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb,
1459*b274feedSAvi Kivity         0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc,
1460*b274feedSAvi Kivity         0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd,
1461*b274feedSAvi Kivity         0x130058be, 0x130158be, 0x131058be, 0x131158be,
1462*b274feedSAvi Kivity         0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf,
1463*b274feedSAvi Kivity         0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0,
1464*b274feedSAvi Kivity         0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1,
1465*b274feedSAvi Kivity         0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2,
1466*b274feedSAvi Kivity         0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3,
1467*b274feedSAvi Kivity         0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4,
1468*b274feedSAvi Kivity         0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5,
1469*b274feedSAvi Kivity         0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6,
1470*b274feedSAvi Kivity         0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7,
1471*b274feedSAvi Kivity         0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8,
1472*b274feedSAvi Kivity         0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9,
1473*b274feedSAvi Kivity         0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca,
1474*b274feedSAvi Kivity         0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb,
1475*b274feedSAvi Kivity         0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc,
1476*b274feedSAvi Kivity         0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd,
1477*b274feedSAvi Kivity         0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce,
1478*b274feedSAvi Kivity         0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf,
1479*b274feedSAvi Kivity         0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0,
1480*b274feedSAvi Kivity         0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1,
1481*b274feedSAvi Kivity         0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2,
1482*b274feedSAvi Kivity         0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3,
1483*b274feedSAvi Kivity         0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4,
1484*b274feedSAvi Kivity         0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5,
1485*b274feedSAvi Kivity         0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6,
1486*b274feedSAvi Kivity         0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7,
1487*b274feedSAvi Kivity         0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8,
1488*b274feedSAvi Kivity         0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9,
1489*b274feedSAvi Kivity         0x170074da, 0x170174da, 0x171074da, 0x171174da,
1490*b274feedSAvi Kivity         0x130075db, 0x130175db, 0x131075db, 0x131175db,
1491*b274feedSAvi Kivity         0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc,
1492*b274feedSAvi Kivity         0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd,
1493*b274feedSAvi Kivity         0x170078de, 0x170178de, 0x171078de, 0x171178de,
1494*b274feedSAvi Kivity         0x130079df, 0x130179df, 0x131079df, 0x131179df,
1495*b274feedSAvi Kivity         0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0,
1496*b274feedSAvi Kivity         0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1,
1497*b274feedSAvi Kivity         0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2,
1498*b274feedSAvi Kivity         0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3,
1499*b274feedSAvi Kivity         0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4,
1500*b274feedSAvi Kivity         0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5,
1501*b274feedSAvi Kivity         0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6,
1502*b274feedSAvi Kivity         0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7,
1503*b274feedSAvi Kivity         0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8,
1504*b274feedSAvi Kivity         0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9,
1505*b274feedSAvi Kivity         0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea,
1506*b274feedSAvi Kivity         0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb,
1507*b274feedSAvi Kivity         0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec,
1508*b274feedSAvi Kivity         0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed,
1509*b274feedSAvi Kivity         0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee,
1510*b274feedSAvi Kivity         0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef,
1511*b274feedSAvi Kivity         0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0,
1512*b274feedSAvi Kivity         0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1,
1513*b274feedSAvi Kivity         0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2,
1514*b274feedSAvi Kivity         0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3,
1515*b274feedSAvi Kivity         0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4,
1516*b274feedSAvi Kivity         0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5,
1517*b274feedSAvi Kivity         0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6,
1518*b274feedSAvi Kivity         0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7,
1519*b274feedSAvi Kivity         0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8,
1520*b274feedSAvi Kivity         0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9,
1521*b274feedSAvi Kivity         0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa,
1522*b274feedSAvi Kivity         0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb,
1523*b274feedSAvi Kivity         0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc,
1524*b274feedSAvi Kivity         0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd,
1525*b274feedSAvi Kivity         0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe,
1526*b274feedSAvi Kivity         0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff,
1527*b274feedSAvi Kivity     };
1528*b274feedSAvi Kivity 
1529*b274feedSAvi Kivity     MK_INSN(das, "das");
1530*b274feedSAvi Kivity 
1531*b274feedSAvi Kivity     for (i = 0; i < 1024; ++i) {
1532*b274feedSAvi Kivity         unsigned tmp = test_cases[i];
1533*b274feedSAvi Kivity         inregs.eax = tmp & 0xff;
1534*b274feedSAvi Kivity         inregs.eflags = (tmp >> 16) & 0xff;
1535*b274feedSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs,
1536*b274feedSAvi Kivity 			      insn_das,
1537*b274feedSAvi Kivity 			      insn_das_end - insn_das);
1538*b274feedSAvi Kivity 
1539*b274feedSAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX)
1540*b274feedSAvi Kivity             || outregs.eax != ((tmp >> 8) & 0xff)
1541*b274feedSAvi Kivity             || (outregs.eflags & 0xff) != (tmp >> 24)) {
1542*b274feedSAvi Kivity 		print_serial("DAS Test: FAIL\n");
1543*b274feedSAvi Kivity                 return;
1544*b274feedSAvi Kivity         }
1545*b274feedSAvi Kivity     }
1546*b274feedSAvi Kivity     print_serial("DAS Test: PASS\n");
1547*b274feedSAvi Kivity }
1548*b274feedSAvi Kivity 
15497d36db35SAvi Kivity void realmode_start(void)
15507d36db35SAvi Kivity {
15517d36db35SAvi Kivity 	test_null();
15527d36db35SAvi Kivity 
15537d36db35SAvi Kivity 	test_shld();
15547d36db35SAvi Kivity 	test_push_pop();
15557d36db35SAvi Kivity 	test_pusha_popa();
15567d36db35SAvi Kivity 	test_mov_imm();
15577d36db35SAvi Kivity 	test_cmp_imm();
15587d36db35SAvi Kivity 	test_add_imm();
15597d36db35SAvi Kivity 	test_sub_imm();
15607d36db35SAvi Kivity 	test_xor_imm();
15617d36db35SAvi Kivity 	test_io();
15627d36db35SAvi Kivity 	test_eflags_insn();
15637d36db35SAvi Kivity 	test_jcc_short();
15647d36db35SAvi Kivity 	test_jcc_near();
15657d36db35SAvi Kivity 	/* test_call() uses short jump so call it after testing jcc */
15667d36db35SAvi Kivity 	test_call();
15677d36db35SAvi Kivity 	/* long jmp test uses call near so test it after testing call */
15687d36db35SAvi Kivity 	test_long_jmp();
15697d36db35SAvi Kivity 	test_xchg();
15707d36db35SAvi Kivity 	test_iret();
157196b9ca1eSMohammed Gamal 	test_int();
1572fa74f8a6SMohammed Gamal 	test_imul();
157359317bd1SMohammed Gamal 	test_mul();
15740d4c7614SMohammed Gamal 	test_div();
15750d4c7614SMohammed Gamal 	test_idiv();
1576eacef4e2SWei Yongjun 	test_loopcc();
15776e293cf5SWei Yongjun 	test_cbw();
1578*b274feedSAvi Kivity 	test_das();
15797d36db35SAvi Kivity 
15807d36db35SAvi Kivity 	exit(0);
15817d36db35SAvi Kivity }
15827d36db35SAvi Kivity 
15837d36db35SAvi Kivity unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff };
15847d36db35SAvi Kivity 
15857d36db35SAvi Kivity struct __attribute__((packed)) {
15867d36db35SAvi Kivity 	unsigned short limit;
15877d36db35SAvi Kivity 	void *base;
15887d36db35SAvi Kivity } r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt };
15897d36db35SAvi Kivity 
15907d36db35SAvi Kivity asm(
15917d36db35SAvi Kivity 	".section .init \n\t"
15927d36db35SAvi Kivity 
15937d36db35SAvi Kivity 	".code32 \n\t"
15947d36db35SAvi Kivity 
15957d36db35SAvi Kivity 	"mb_magic = 0x1BADB002 \n\t"
15967d36db35SAvi Kivity 	"mb_flags = 0x0 \n\t"
15977d36db35SAvi Kivity 
15987d36db35SAvi Kivity 	"# multiboot header \n\t"
15997d36db35SAvi Kivity 	".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t"
16007d36db35SAvi Kivity 
16017d36db35SAvi Kivity 	".globl start \n\t"
16027d36db35SAvi Kivity 	".data \n\t"
16037d36db35SAvi Kivity 	". = . + 4096 \n\t"
16047d36db35SAvi Kivity 	"stacktop: \n\t"
16057d36db35SAvi Kivity 
16067d36db35SAvi Kivity 	".text \n\t"
16077d36db35SAvi Kivity 	"start: \n\t"
16087d36db35SAvi Kivity 	"lgdt r_gdt_descr \n\t"
16097d36db35SAvi Kivity 	"ljmp $8, $1f; 1: \n\t"
16107d36db35SAvi Kivity 	".code16gcc \n\t"
16117d36db35SAvi Kivity 	"mov $16, %eax \n\t"
16127d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
16137d36db35SAvi Kivity 	"mov %ax, %es \n\t"
16147d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
16157d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
16167d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
16177d36db35SAvi Kivity 	"mov %cr0, %eax \n\t"
16187d36db35SAvi Kivity 	"btc $0, %eax \n\t"
16197d36db35SAvi Kivity 	"mov %eax, %cr0 \n\t"
16207d36db35SAvi Kivity 	"ljmp $0, $realmode_entry \n\t"
16217d36db35SAvi Kivity 
16227d36db35SAvi Kivity 	"realmode_entry: \n\t"
16237d36db35SAvi Kivity 
16247d36db35SAvi Kivity 	"xor %ax, %ax \n\t"
16257d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
16267d36db35SAvi Kivity 	"mov %ax, %es \n\t"
16277d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
16287d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
16297d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
16307d36db35SAvi Kivity 	"mov $stacktop, %esp\n\t"
16317d36db35SAvi Kivity 	"ljmp $0, $realmode_start \n\t"
16327d36db35SAvi Kivity 
16337d36db35SAvi Kivity 	".code16gcc \n\t"
16347d36db35SAvi Kivity 	);
1635