xref: /kvm-unit-tests/x86/realmode.c (revision 1a4c03a0d86de3db47fc7c328a2e274eb8d28684)
1f366255fSPaolo Bonzini #ifndef USE_SERIAL
2f366255fSPaolo Bonzini #define USE_SERIAL
3f366255fSPaolo Bonzini #endif
4f366255fSPaolo Bonzini 
57d36db35SAvi Kivity asm(".code16gcc");
67d36db35SAvi Kivity 
77d36db35SAvi Kivity typedef unsigned char u8;
87d36db35SAvi Kivity typedef unsigned short u16;
97d36db35SAvi Kivity typedef unsigned u32;
107d36db35SAvi Kivity typedef unsigned long long u64;
117d36db35SAvi Kivity 
127d36db35SAvi Kivity void test_function(void);
137d36db35SAvi Kivity 
147d36db35SAvi Kivity asm(
157d36db35SAvi Kivity 	"test_function: \n\t"
167d36db35SAvi Kivity 	"mov $0x1234, %eax \n\t"
177d36db35SAvi Kivity 	"ret"
187d36db35SAvi Kivity    );
197d36db35SAvi Kivity 
207d36db35SAvi Kivity static int strlen(const char *str)
217d36db35SAvi Kivity {
227d36db35SAvi Kivity 	int n;
237d36db35SAvi Kivity 
247d36db35SAvi Kivity 	for (n = 0; *str; ++str)
257d36db35SAvi Kivity 		++n;
267d36db35SAvi Kivity 	return n;
277d36db35SAvi Kivity }
287d36db35SAvi Kivity 
29f366255fSPaolo Bonzini static void outb(u8 data, u16 port)
30f366255fSPaolo Bonzini {
31f366255fSPaolo Bonzini 	asm volatile("out %0, %1" : : "a"(data), "d"(port));
32f366255fSPaolo Bonzini }
33f366255fSPaolo Bonzini 
34f366255fSPaolo Bonzini #ifdef USE_SERIAL
35f366255fSPaolo Bonzini static int serial_iobase = 0x3f8;
36f366255fSPaolo Bonzini static int serial_inited = 0;
37f366255fSPaolo Bonzini 
38f366255fSPaolo Bonzini static u8 inb(u16 port)
39f366255fSPaolo Bonzini {
40f366255fSPaolo Bonzini 	u8 data;
41f366255fSPaolo Bonzini 	asm volatile("in %1, %0" : "=a"(data) : "d"(port));
42f366255fSPaolo Bonzini 	return data;
43f366255fSPaolo Bonzini }
44f366255fSPaolo Bonzini 
45f366255fSPaolo Bonzini static void serial_outb(char ch)
46f366255fSPaolo Bonzini {
47f366255fSPaolo Bonzini 	u8 lsr;
48f366255fSPaolo Bonzini 
49f366255fSPaolo Bonzini 	do {
50f366255fSPaolo Bonzini 		lsr = inb(serial_iobase + 0x05);
51f366255fSPaolo Bonzini 	} while (!(lsr & 0x20));
52f366255fSPaolo Bonzini 
53f366255fSPaolo Bonzini 	outb(ch, serial_iobase + 0x00);
54f366255fSPaolo Bonzini }
55f366255fSPaolo Bonzini 
56f366255fSPaolo Bonzini static void serial_init(void)
57f366255fSPaolo Bonzini {
58f366255fSPaolo Bonzini 	u8 lcr;
59f366255fSPaolo Bonzini 
60f366255fSPaolo Bonzini 	/* set DLAB */
61f366255fSPaolo Bonzini 	lcr = inb(serial_iobase + 0x03);
62f366255fSPaolo Bonzini 	lcr |= 0x80;
63f366255fSPaolo Bonzini 	outb(lcr, serial_iobase + 0x03);
64f366255fSPaolo Bonzini 
65f366255fSPaolo Bonzini 	/* set baud rate to 115200 */
66f366255fSPaolo Bonzini 	outb(0x01, serial_iobase + 0x00);
67f366255fSPaolo Bonzini 	outb(0x00, serial_iobase + 0x01);
68f366255fSPaolo Bonzini 
69f366255fSPaolo Bonzini 	/* clear DLAB */
70f366255fSPaolo Bonzini 	lcr = inb(serial_iobase + 0x03);
71f366255fSPaolo Bonzini 	lcr &= ~0x80;
72f366255fSPaolo Bonzini 	outb(lcr, serial_iobase + 0x03);
73f366255fSPaolo Bonzini }
74f366255fSPaolo Bonzini #endif
75f366255fSPaolo Bonzini 
767d36db35SAvi Kivity static void print_serial(const char *buf)
777d36db35SAvi Kivity {
787d36db35SAvi Kivity 	unsigned long len = strlen(buf);
79f366255fSPaolo Bonzini #ifdef USE_SERIAL
80f366255fSPaolo Bonzini 	unsigned long i;
81f366255fSPaolo Bonzini 	if (!serial_inited) {
82f366255fSPaolo Bonzini 	    serial_init();
83f366255fSPaolo Bonzini 	    serial_inited = 1;
84f366255fSPaolo Bonzini 	}
857d36db35SAvi Kivity 
86f366255fSPaolo Bonzini 	for (i = 0; i < len; i++) {
87f366255fSPaolo Bonzini 	    serial_outb(buf[i]);
88f366255fSPaolo Bonzini 	}
89f366255fSPaolo Bonzini #else
905edbb9aeSPaolo Bonzini 	asm volatile ("addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1));
91f366255fSPaolo Bonzini #endif
927d36db35SAvi Kivity }
937d36db35SAvi Kivity 
947d36db35SAvi Kivity static void exit(int code)
957d36db35SAvi Kivity {
96f366255fSPaolo Bonzini 	outb(code, 0xf4);
977d36db35SAvi Kivity }
987d36db35SAvi Kivity 
997d36db35SAvi Kivity struct regs {
1007d36db35SAvi Kivity 	u32 eax, ebx, ecx, edx;
1017d36db35SAvi Kivity 	u32 esi, edi, esp, ebp;
1027d36db35SAvi Kivity 	u32 eip, eflags;
1037d36db35SAvi Kivity };
1047d36db35SAvi Kivity 
1057d36db35SAvi Kivity static u64 gdt[] = {
1067d36db35SAvi Kivity 	0,
1077d36db35SAvi Kivity 	0x00cf9b000000ffffull, // flat 32-bit code segment
1087d36db35SAvi Kivity 	0x00cf93000000ffffull, // flat 32-bit data segment
1097d36db35SAvi Kivity };
1107d36db35SAvi Kivity 
1117d36db35SAvi Kivity static struct {
1127d36db35SAvi Kivity 	u16 limit;
1137d36db35SAvi Kivity 	void *base;
1147d36db35SAvi Kivity } __attribute__((packed)) gdt_descr = {
1157d36db35SAvi Kivity 	sizeof(gdt) - 1,
1167d36db35SAvi Kivity 	gdt,
1177d36db35SAvi Kivity };
1187d36db35SAvi Kivity 
119d4dc402cSAvi Kivity struct insn_desc {
120d4dc402cSAvi Kivity     u16 ptr;
121d4dc402cSAvi Kivity     u16 len;
122d4dc402cSAvi Kivity };
123d4dc402cSAvi Kivity 
12418253fdeSAvi Kivity static struct regs inregs, outregs;
12518253fdeSAvi Kivity 
12618253fdeSAvi Kivity static void exec_in_big_real_mode(struct insn_desc *insn)
1277d36db35SAvi Kivity {
1287d36db35SAvi Kivity 	unsigned long tmp;
1297d36db35SAvi Kivity 	static struct regs save;
1307d36db35SAvi Kivity 	int i;
1317d36db35SAvi Kivity 	extern u8 test_insn[], test_insn_end[];
1327d36db35SAvi Kivity 
133d4dc402cSAvi Kivity 	for (i = 0; i < insn->len; ++i)
134d4dc402cSAvi Kivity 	    test_insn[i] = ((u8 *)(unsigned long)insn->ptr)[i];
1357d36db35SAvi Kivity 	for (; i < test_insn_end - test_insn; ++i)
1367d36db35SAvi Kivity 		test_insn[i] = 0x90; // nop
1377d36db35SAvi Kivity 
13818253fdeSAvi Kivity 	save = inregs;
1397d36db35SAvi Kivity 	asm volatile(
1407d36db35SAvi Kivity 		"lgdtl %[gdt_descr] \n\t"
1417d36db35SAvi Kivity 		"mov %%cr0, %[tmp] \n\t"
1427d36db35SAvi Kivity 		"or $1, %[tmp] \n\t"
1437d36db35SAvi Kivity 		"mov %[tmp], %%cr0 \n\t"
1447d36db35SAvi Kivity 		"mov %[bigseg], %%gs \n\t"
1457d36db35SAvi Kivity 		"and $-2, %[tmp] \n\t"
1467d36db35SAvi Kivity 		"mov %[tmp], %%cr0 \n\t"
1477d36db35SAvi Kivity 
14832001692SAvi Kivity                 "pushw %[save]+36; popfw \n\t"
1497d36db35SAvi Kivity 		"xchg %%eax, %[save]+0 \n\t"
1507d36db35SAvi Kivity 		"xchg %%ebx, %[save]+4 \n\t"
1517d36db35SAvi Kivity 		"xchg %%ecx, %[save]+8 \n\t"
1527d36db35SAvi Kivity 		"xchg %%edx, %[save]+12 \n\t"
1537d36db35SAvi Kivity 		"xchg %%esi, %[save]+16 \n\t"
1547d36db35SAvi Kivity 		"xchg %%edi, %[save]+20 \n\t"
1557d36db35SAvi Kivity 		"xchg %%esp, %[save]+24 \n\t"
1567d36db35SAvi Kivity 		"xchg %%ebp, %[save]+28 \n\t"
1577d36db35SAvi Kivity 
1587d36db35SAvi Kivity 		"test_insn: . = . + 32\n\t"
1597d36db35SAvi Kivity 		"test_insn_end: \n\t"
1607d36db35SAvi Kivity 
1617d36db35SAvi Kivity 		"xchg %%eax, %[save]+0 \n\t"
1627d36db35SAvi Kivity 		"xchg %%ebx, %[save]+4 \n\t"
1637d36db35SAvi Kivity 		"xchg %%ecx, %[save]+8 \n\t"
1647d36db35SAvi Kivity 		"xchg %%edx, %[save]+12 \n\t"
1657d36db35SAvi Kivity 		"xchg %%esi, %[save]+16 \n\t"
1667d36db35SAvi Kivity 		"xchg %%edi, %[save]+20 \n\t"
1677d36db35SAvi Kivity 		"xchg %%esp, %[save]+24 \n\t"
1687d36db35SAvi Kivity 		"xchg %%ebp, %[save]+28 \n\t"
1697d36db35SAvi Kivity 
1707d36db35SAvi Kivity 		/* Save EFLAGS in outregs*/
1717d36db35SAvi Kivity 		"pushfl \n\t"
1727d36db35SAvi Kivity 		"popl %[save]+36 \n\t"
1737d36db35SAvi Kivity 
1745edbb9aeSPaolo Bonzini 		/* Restore DF for the harness code */
1755edbb9aeSPaolo Bonzini 		"cld\n\t"
1767d36db35SAvi Kivity 		"xor %[tmp], %[tmp] \n\t"
1777d36db35SAvi Kivity 		"mov %[tmp], %%gs \n\t"
1787d36db35SAvi Kivity 		: [tmp]"=&r"(tmp), [save]"+m"(save)
1797d36db35SAvi Kivity 		: [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16)
1807d36db35SAvi Kivity 		: "cc", "memory"
1817d36db35SAvi Kivity 		);
18218253fdeSAvi Kivity 	outregs = save;
1837d36db35SAvi Kivity }
1847d36db35SAvi Kivity 
1857d36db35SAvi Kivity #define R_AX 1
1867d36db35SAvi Kivity #define R_BX 2
1877d36db35SAvi Kivity #define R_CX 4
1887d36db35SAvi Kivity #define R_DX 8
1897d36db35SAvi Kivity #define R_SI 16
1907d36db35SAvi Kivity #define R_DI 32
1917d36db35SAvi Kivity #define R_SP 64
1927d36db35SAvi Kivity #define R_BP 128
1937d36db35SAvi Kivity 
19418253fdeSAvi Kivity int regs_equal(int ignore)
1957d36db35SAvi Kivity {
19618253fdeSAvi Kivity 	const u32 *p1 = &inregs.eax, *p2 = &outregs.eax;  // yuck
1977d36db35SAvi Kivity 	int i;
1987d36db35SAvi Kivity 
1997d36db35SAvi Kivity 	for (i = 0; i < 8; ++i)
2007d36db35SAvi Kivity 		if (!(ignore & (1 << i)) && p1[i] != p2[i])
2017d36db35SAvi Kivity 			return 0;
2027d36db35SAvi Kivity 	return 1;
2037d36db35SAvi Kivity }
2047d36db35SAvi Kivity 
2056055ea1fSAvi Kivity static void report(const char *name, u16 regs_ignore, _Bool ok)
20681050840SAvi Kivity {
2076055ea1fSAvi Kivity     if (!regs_equal(regs_ignore)) {
2086055ea1fSAvi Kivity 	ok = 0;
2096055ea1fSAvi Kivity     }
21081050840SAvi Kivity     print_serial(ok ? "PASS: " : "FAIL: ");
21181050840SAvi Kivity     print_serial(name);
21281050840SAvi Kivity     print_serial("\n");
21381050840SAvi Kivity }
21481050840SAvi Kivity 
2157d36db35SAvi Kivity #define MK_INSN(name, str)				\
2167d36db35SAvi Kivity     asm (						\
217d4dc402cSAvi Kivity 	 ".pushsection .data.insn  \n\t"		\
218d4dc402cSAvi Kivity 	 "insn_" #name ": \n\t"				\
219d4dc402cSAvi Kivity 	 ".word 1001f, 1002f - 1001f \n\t"		\
220d4dc402cSAvi Kivity 	 ".popsection \n\t"				\
221d4dc402cSAvi Kivity 	 ".pushsection .text.insn, \"ax\" \n\t"		\
222d4dc402cSAvi Kivity 	 "1001: \n\t"					\
223d4dc402cSAvi Kivity 	 "insn_code_" #name ": " str " \n\t"		\
224d4dc402cSAvi Kivity 	 "1002: \n\t"					\
225d4dc402cSAvi Kivity 	 ".popsection"					\
2267d36db35SAvi Kivity     );							\
227d4dc402cSAvi Kivity     extern struct insn_desc insn_##name;
2287d36db35SAvi Kivity 
2297d36db35SAvi Kivity void test_xchg(void)
2307d36db35SAvi Kivity {
2317d36db35SAvi Kivity 	MK_INSN(xchg_test1, "xchg %eax,%eax\n\t");
2327d36db35SAvi Kivity 	MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t");
2337d36db35SAvi Kivity 	MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t");
2347d36db35SAvi Kivity 	MK_INSN(xchg_test4, "xchg %eax,%edx\n\t");
2357d36db35SAvi Kivity 	MK_INSN(xchg_test5, "xchg %eax,%esi\n\t");
2367d36db35SAvi Kivity 	MK_INSN(xchg_test6, "xchg %eax,%edi\n\t");
2377d36db35SAvi Kivity 	MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t");
2387d36db35SAvi Kivity 	MK_INSN(xchg_test8, "xchg %eax,%esp\n\t");
2397d36db35SAvi Kivity 
24018253fdeSAvi Kivity 	inregs = (struct regs){ .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7};
2417d36db35SAvi Kivity 
24218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xchg_test1);
2436055ea1fSAvi Kivity 	report("xchg 1", 0, 1);
24418253fdeSAvi Kivity 
24518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xchg_test2);
2466055ea1fSAvi Kivity 	report("xchg 2", R_AX | R_BX,
2476055ea1fSAvi Kivity 	       outregs.eax == inregs.ebx && outregs.ebx == inregs.eax);
2487d36db35SAvi Kivity 
24918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xchg_test3);
2506055ea1fSAvi Kivity 	report("xchg 3", R_AX | R_CX,
2516055ea1fSAvi Kivity 	       outregs.eax == inregs.ecx && outregs.ecx == inregs.eax);
2527d36db35SAvi Kivity 
25318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xchg_test4);
2546055ea1fSAvi Kivity 	report("xchg 4", R_AX | R_DX,
2556055ea1fSAvi Kivity 	       outregs.eax == inregs.edx && outregs.edx == inregs.eax);
2567d36db35SAvi Kivity 
25718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xchg_test5);
2586055ea1fSAvi Kivity 	report("xchg 5", R_AX | R_SI,
2596055ea1fSAvi Kivity 	       outregs.eax == inregs.esi && outregs.esi == inregs.eax);
2607d36db35SAvi Kivity 
26118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xchg_test6);
2626055ea1fSAvi Kivity 	report("xchg 6", R_AX | R_DI,
2636055ea1fSAvi Kivity 	       outregs.eax == inregs.edi && outregs.edi == inregs.eax);
2647d36db35SAvi Kivity 
26518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xchg_test7);
2666055ea1fSAvi Kivity 	report("xchg 7", R_AX | R_BP,
2676055ea1fSAvi Kivity 	       outregs.eax == inregs.ebp && outregs.ebp == inregs.eax);
2687d36db35SAvi Kivity 
26918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xchg_test8);
2706055ea1fSAvi Kivity 	report("xchg 8", R_AX | R_SP,
2716055ea1fSAvi Kivity 	       outregs.eax == inregs.esp && outregs.esp == inregs.eax);
2727d36db35SAvi Kivity }
2737d36db35SAvi Kivity 
2747d36db35SAvi Kivity void test_shld(void)
2757d36db35SAvi Kivity {
2767d36db35SAvi Kivity 	MK_INSN(shld_test, "shld $8,%edx,%eax\n\t");
2777d36db35SAvi Kivity 
27818253fdeSAvi Kivity 	inregs = (struct regs){ .eax = 0xbe, .edx = 0xef000000 };
27918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_shld_test);
2806055ea1fSAvi Kivity 	report("shld", ~0, outregs.eax == 0xbeef);
2817d36db35SAvi Kivity }
2827d36db35SAvi Kivity 
2837d36db35SAvi Kivity void test_mov_imm(void)
2847d36db35SAvi Kivity {
2857d36db35SAvi Kivity 	MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax");
2867d36db35SAvi Kivity 	MK_INSN(mov_r16_imm_1, "mov $1234, %ax");
2877d36db35SAvi Kivity 	MK_INSN(mov_r8_imm_1, "mov $0x12, %ah");
2887d36db35SAvi Kivity 	MK_INSN(mov_r8_imm_2, "mov $0x34, %al");
2897d36db35SAvi Kivity 	MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t");
2907d36db35SAvi Kivity 
29118253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
29218253fdeSAvi Kivity 
29318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mov_r16_imm_1);
2946055ea1fSAvi Kivity 	report("mov 1", R_AX, outregs.eax == 1234);
2957d36db35SAvi Kivity 
2967d36db35SAvi Kivity 	/* test mov $imm, %eax */
29718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mov_r32_imm_1);
2986055ea1fSAvi Kivity 	report("mov 2", R_AX, outregs.eax == 1234567890);
2997d36db35SAvi Kivity 
3007d36db35SAvi Kivity 	/* test mov $imm, %al/%ah */
30118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mov_r8_imm_1);
3026055ea1fSAvi Kivity 	report("mov 3", R_AX, outregs.eax == 0x1200);
3037d36db35SAvi Kivity 
30418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mov_r8_imm_2);
3056055ea1fSAvi Kivity 	report("mov 4", R_AX, outregs.eax == 0x34);
3067d36db35SAvi Kivity 
30718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mov_r8_imm_3);
3086055ea1fSAvi Kivity 	report("mov 5", R_AX, outregs.eax == 0x1234);
3097d36db35SAvi Kivity }
3107d36db35SAvi Kivity 
3117d36db35SAvi Kivity void test_sub_imm(void)
3127d36db35SAvi Kivity {
3137d36db35SAvi Kivity 	MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t");
3147d36db35SAvi Kivity 	MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t");
3157d36db35SAvi Kivity 	MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t");
3167d36db35SAvi Kivity 	MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t");
3177d36db35SAvi Kivity 
31818253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
31918253fdeSAvi Kivity 
32018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_sub_r16_imm_1);
3216055ea1fSAvi Kivity 	report("sub 1", R_AX, outregs.eax == 1224);
3227d36db35SAvi Kivity 
3237d36db35SAvi Kivity 	/* test mov $imm, %eax */
32418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_sub_r32_imm_1);
3256055ea1fSAvi Kivity 	report("sub 2", R_AX, outregs.eax == 1234567880);
3267d36db35SAvi Kivity 
3277d36db35SAvi Kivity 	/* test mov $imm, %al/%ah */
32818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_sub_r8_imm_1);
3296055ea1fSAvi Kivity 	report("sub 3", R_AX, outregs.eax == 0x0200);
3307d36db35SAvi Kivity 
33118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_sub_r8_imm_2);
3326055ea1fSAvi Kivity 	report("sub 4", R_AX, outregs.eax == 0x24);
3337d36db35SAvi Kivity }
3347d36db35SAvi Kivity 
3357d36db35SAvi Kivity void test_xor_imm(void)
3367d36db35SAvi Kivity {
3377d36db35SAvi Kivity 	MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t");
3387d36db35SAvi Kivity 	MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t");
3397d36db35SAvi Kivity 	MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t");
3407d36db35SAvi Kivity 	MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t");
3417d36db35SAvi Kivity 
34218253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
34318253fdeSAvi Kivity 
34418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xor_r16_imm_1);
3456055ea1fSAvi Kivity 	report("xor 1", R_AX, outregs.eax == 0);
3467d36db35SAvi Kivity 
3477d36db35SAvi Kivity 	/* test mov $imm, %eax */
34818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xor_r32_imm_1);
3496055ea1fSAvi Kivity 	report("xor 2", R_AX, outregs.eax == 0);
3507d36db35SAvi Kivity 
3517d36db35SAvi Kivity 	/* test mov $imm, %al/%ah */
35218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xor_r8_imm_1);
3536055ea1fSAvi Kivity 	report("xor 3", R_AX, outregs.eax == 0);
3547d36db35SAvi Kivity 
35518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_xor_r8_imm_2);
3566055ea1fSAvi Kivity 	report("xor 4", R_AX, outregs.eax == 0);
3577d36db35SAvi Kivity }
3587d36db35SAvi Kivity 
3597d36db35SAvi Kivity void test_cmp_imm(void)
3607d36db35SAvi Kivity {
3617d36db35SAvi Kivity 	MK_INSN(cmp_test1, "mov $0x34, %al\n\t"
3627d36db35SAvi Kivity 			   "cmp $0x34, %al\n\t");
3637d36db35SAvi Kivity 	MK_INSN(cmp_test2, "mov $0x34, %al\n\t"
3647d36db35SAvi Kivity 			   "cmp $0x39, %al\n\t");
3657d36db35SAvi Kivity 	MK_INSN(cmp_test3, "mov $0x34, %al\n\t"
3667d36db35SAvi Kivity 			   "cmp $0x24, %al\n\t");
3677d36db35SAvi Kivity 
36818253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
36918253fdeSAvi Kivity 
3707d36db35SAvi Kivity 	/* test cmp imm8 with AL */
3717d36db35SAvi Kivity 	/* ZF: (bit 6) Zero Flag becomes 1 if an operation results
3727d36db35SAvi Kivity 	 * in a 0 writeback, or 0 register
3737d36db35SAvi Kivity 	 */
37418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cmp_test1);
3756055ea1fSAvi Kivity 	report("cmp 1", ~0, (outregs.eflags & (1<<6)) == (1<<6));
3767d36db35SAvi Kivity 
37718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cmp_test2);
3786055ea1fSAvi Kivity 	report("cmp 2", ~0, (outregs.eflags & (1<<6)) == 0);
3797d36db35SAvi Kivity 
38018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cmp_test3);
3816055ea1fSAvi Kivity 	report("cmp 3", ~0, (outregs.eflags & (1<<6)) == 0);
3827d36db35SAvi Kivity }
3837d36db35SAvi Kivity 
3847d36db35SAvi Kivity void test_add_imm(void)
3857d36db35SAvi Kivity {
3867d36db35SAvi Kivity 	MK_INSN(add_test1, "mov $0x43211234, %eax \n\t"
3877d36db35SAvi Kivity 			   "add $0x12344321, %eax \n\t");
3887d36db35SAvi Kivity 	MK_INSN(add_test2, "mov $0x12, %eax \n\t"
3897d36db35SAvi Kivity 			   "add $0x21, %al\n\t");
3907d36db35SAvi Kivity 
39118253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
39218253fdeSAvi Kivity 
39318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_add_test1);
3946055ea1fSAvi Kivity 	report("add 1", ~0, outregs.eax == 0x55555555);
3957d36db35SAvi Kivity 
39618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_add_test2);
3976055ea1fSAvi Kivity 	report("add 2", ~0, outregs.eax == 0x33);
3987d36db35SAvi Kivity }
3997d36db35SAvi Kivity 
4007d36db35SAvi Kivity void test_eflags_insn(void)
4017d36db35SAvi Kivity {
4027d36db35SAvi Kivity 	MK_INSN(clc, "clc");
403b3261e48SMohammed Gamal 	MK_INSN(stc, "stc");
4047d36db35SAvi Kivity 	MK_INSN(cli, "cli");
4057d36db35SAvi Kivity 	MK_INSN(sti, "sti");
4067d36db35SAvi Kivity 	MK_INSN(cld, "cld");
4077d36db35SAvi Kivity 	MK_INSN(std, "std");
4087d36db35SAvi Kivity 
40918253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
41018253fdeSAvi Kivity 
41118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_clc);
4126055ea1fSAvi Kivity 	report("clc", ~0, (outregs.eflags & 1) == 0);
4137d36db35SAvi Kivity 
41418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_stc);
4156055ea1fSAvi Kivity 	report("stc", ~0, (outregs.eflags & 1) == 1);
416b3261e48SMohammed Gamal 
41718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cli);
4186055ea1fSAvi Kivity 	report("cli", ~0, !(outregs.eflags & (1 << 9)));
4197d36db35SAvi Kivity 
42018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_sti);
4216055ea1fSAvi Kivity 	report("sti", ~0, outregs.eflags & (1 << 9));
4227d36db35SAvi Kivity 
42318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cld);
4246055ea1fSAvi Kivity 	report("cld", ~0, !(outregs.eflags & (1 << 10)));
4257d36db35SAvi Kivity 
42618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_std);
4276055ea1fSAvi Kivity 	report("std", ~0, (outregs.eflags & (1 << 10)));
4287d36db35SAvi Kivity }
4297d36db35SAvi Kivity 
4307d36db35SAvi Kivity void test_io(void)
4317d36db35SAvi Kivity {
4327d36db35SAvi Kivity 	MK_INSN(io_test1, "mov $0xff, %al \n\t"
4337d36db35SAvi Kivity 		          "out %al, $0xe0 \n\t"
4347d36db35SAvi Kivity 		          "mov $0x00, %al \n\t"
4357d36db35SAvi Kivity 			  "in $0xe0, %al \n\t");
4367d36db35SAvi Kivity 	MK_INSN(io_test2, "mov $0xffff, %ax \n\t"
4377d36db35SAvi Kivity 			  "out %ax, $0xe0 \n\t"
4387d36db35SAvi Kivity 			  "mov $0x0000, %ax \n\t"
4397d36db35SAvi Kivity 			  "in $0xe0, %ax \n\t");
4407d36db35SAvi Kivity 	MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t"
4417d36db35SAvi Kivity 			  "out %eax, $0xe0 \n\t"
4427d36db35SAvi Kivity 			  "mov $0x000000, %eax \n\t"
4437d36db35SAvi Kivity 			  "in $0xe0, %eax \n\t");
4447d36db35SAvi Kivity 	MK_INSN(io_test4, "mov $0xe0, %dx \n\t"
4457d36db35SAvi Kivity 			  "mov $0xff, %al \n\t"
4467d36db35SAvi Kivity 			  "out %al, %dx \n\t"
4477d36db35SAvi Kivity 			  "mov $0x00, %al \n\t"
4487d36db35SAvi Kivity 			  "in %dx, %al \n\t");
4497d36db35SAvi Kivity 	MK_INSN(io_test5, "mov $0xe0, %dx \n\t"
4507d36db35SAvi Kivity 			  "mov $0xffff, %ax \n\t"
4517d36db35SAvi Kivity 			  "out %ax, %dx \n\t"
4527d36db35SAvi Kivity 			  "mov $0x0000, %ax \n\t"
4537d36db35SAvi Kivity 			  "in %dx, %ax \n\t");
4547d36db35SAvi Kivity 	MK_INSN(io_test6, "mov $0xe0, %dx \n\t"
4557d36db35SAvi Kivity 			  "mov $0xffffffff, %eax \n\t"
4567d36db35SAvi Kivity 			  "out %eax, %dx \n\t"
4577d36db35SAvi Kivity 			  "mov $0x00000000, %eax \n\t"
4587d36db35SAvi Kivity 			  "in %dx, %eax \n\t");
4597d36db35SAvi Kivity 
46018253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
46118253fdeSAvi Kivity 
46218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_io_test1);
4636055ea1fSAvi Kivity 	report("pio 1", R_AX, outregs.eax == 0xff);
4647d36db35SAvi Kivity 
46518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_io_test2);
4666055ea1fSAvi Kivity 	report("pio 2", R_AX, outregs.eax == 0xffff);
4677d36db35SAvi Kivity 
46818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_io_test3);
4696055ea1fSAvi Kivity 	report("pio 3", R_AX, outregs.eax == 0xffffffff);
4707d36db35SAvi Kivity 
47118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_io_test4);
4726055ea1fSAvi Kivity 	report("pio 4", R_AX|R_DX, outregs.eax == 0xff);
4737d36db35SAvi Kivity 
47418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_io_test5);
4756055ea1fSAvi Kivity 	report("pio 5", R_AX|R_DX, outregs.eax == 0xffff);
4767d36db35SAvi Kivity 
47718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_io_test6);
4786055ea1fSAvi Kivity 	report("pio 6", R_AX|R_DX, outregs.eax == 0xffffffff);
4797d36db35SAvi Kivity }
4807d36db35SAvi Kivity 
481c0b7268dSAvi Kivity asm ("retf: lretw");
482c0b7268dSAvi Kivity extern void retf();
483c0b7268dSAvi Kivity 
4847d36db35SAvi Kivity void test_call(void)
4857d36db35SAvi Kivity {
4867d36db35SAvi Kivity 	u32 esp[16];
487c0b7268dSAvi Kivity 	u32 addr;
4887d36db35SAvi Kivity 
48918253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
4907d36db35SAvi Kivity 	inregs.esp = (u32)esp;
4917d36db35SAvi Kivity 
4927d36db35SAvi Kivity 	MK_INSN(call1, "mov $test_function, %eax \n\t"
4937d36db35SAvi Kivity 		       "call *%eax\n\t");
4947d36db35SAvi Kivity 	MK_INSN(call_near1, "jmp 2f\n\t"
4957d36db35SAvi Kivity 			    "1: mov $0x1234, %eax\n\t"
4967d36db35SAvi Kivity 			    "ret\n\t"
4977d36db35SAvi Kivity 			    "2: call 1b\t");
4987d36db35SAvi Kivity 	MK_INSN(call_near2, "call 1f\n\t"
4997d36db35SAvi Kivity 			    "jmp 2f\n\t"
5007d36db35SAvi Kivity 			    "1: mov $0x1234, %eax\n\t"
5017d36db35SAvi Kivity 			    "ret\n\t"
5027d36db35SAvi Kivity 			    "2:\t");
503c0b7268dSAvi Kivity 	MK_INSN(call_far1,  "lcallw *(%ebx)\n\t");
504556d2680SWei Yongjun 	MK_INSN(call_far2,  "lcallw $0, $retf\n\t");
505c6061817SAvi Kivity 	MK_INSN(ret_imm,    "sub $10, %sp; jmp 2f; 1: retw $10; 2: callw 1b");
5067d36db35SAvi Kivity 
50718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_call1);
5086055ea1fSAvi Kivity 	report("call 1", R_AX, outregs.eax == 0x1234);
5097d36db35SAvi Kivity 
51018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_call_near1);
5116055ea1fSAvi Kivity 	report("call near 1", R_AX, outregs.eax == 0x1234);
5127d36db35SAvi Kivity 
51318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_call_near2);
5146055ea1fSAvi Kivity 	report("call near 2", R_AX, outregs.eax == 0x1234);
515c0b7268dSAvi Kivity 
516c0b7268dSAvi Kivity 	addr = (((unsigned)retf >> 4) << 16) | ((unsigned)retf & 0x0f);
517c0b7268dSAvi Kivity 	inregs.ebx = (unsigned)&addr;
51818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_call_far1);
5196055ea1fSAvi Kivity 	report("call far 1", 0, 1);
520c6061817SAvi Kivity 
521556d2680SWei Yongjun 	exec_in_big_real_mode(&insn_call_far2);
522556d2680SWei Yongjun 	report("call far 2", 0, 1);
523556d2680SWei Yongjun 
52418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_ret_imm);
5256055ea1fSAvi Kivity 	report("ret imm 1", 0, 1);
5267d36db35SAvi Kivity }
5277d36db35SAvi Kivity 
5287d36db35SAvi Kivity void test_jcc_short(void)
5297d36db35SAvi Kivity {
5307d36db35SAvi Kivity 	MK_INSN(jnz_short1, "jnz 1f\n\t"
5317d36db35SAvi Kivity 			    "mov $0x1234, %eax\n\t"
5327d36db35SAvi Kivity 		            "1:\n\t");
5337d36db35SAvi Kivity 	MK_INSN(jnz_short2, "1:\n\t"
5347d36db35SAvi Kivity 			    "cmp $0x1234, %eax\n\t"
5357d36db35SAvi Kivity 			    "mov $0x1234, %eax\n\t"
5367d36db35SAvi Kivity 		            "jnz 1b\n\t");
5377d36db35SAvi Kivity 	MK_INSN(jmp_short1, "jmp 1f\n\t"
5387d36db35SAvi Kivity 		      "mov $0x1234, %eax\n\t"
5397d36db35SAvi Kivity 		      "1:\n\t");
5407d36db35SAvi Kivity 
54118253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
5427d36db35SAvi Kivity 
54318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jnz_short1);
5446055ea1fSAvi Kivity 	report("jnz short 1", ~0, 1);
54518253fdeSAvi Kivity 
54618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jnz_short2);
5476055ea1fSAvi Kivity 	report("jnz short 2", R_AX, (outregs.eflags & (1 << 6)));
5487d36db35SAvi Kivity 
54918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jmp_short1);
5506055ea1fSAvi Kivity 	report("jmp short 1", ~0, 1);
5517d36db35SAvi Kivity }
5527d36db35SAvi Kivity 
5537d36db35SAvi Kivity void test_jcc_near(void)
5547d36db35SAvi Kivity {
5557d36db35SAvi Kivity 	/* encode near jmp manually. gas will not do it if offsets < 127 byte */
5567d36db35SAvi Kivity 	MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t"
5577d36db35SAvi Kivity 		           "mov $0x1234, %eax\n\t");
5587d36db35SAvi Kivity 	MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t"
5597d36db35SAvi Kivity 			   "mov $0x1234, %eax\n\t"
5607d36db35SAvi Kivity 		           ".byte 0x0f, 0x85, 0xf0, 0xff\n\t");
5617d36db35SAvi Kivity 	MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t"
5627d36db35SAvi Kivity 		           "mov $0x1234, %eax\n\t");
5637d36db35SAvi Kivity 
56418253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
5657d36db35SAvi Kivity 
56618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jnz_near1);
5676055ea1fSAvi Kivity 	report("jnz near 1", 0, 1);
56818253fdeSAvi Kivity 
56918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jnz_near2);
5706055ea1fSAvi Kivity 	report("jnz near 2", R_AX, outregs.eflags & (1 << 6));
5717d36db35SAvi Kivity 
57218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jmp_near1);
5736055ea1fSAvi Kivity 	report("jmp near 1", 0, 1);
5747d36db35SAvi Kivity }
5757d36db35SAvi Kivity 
5767d36db35SAvi Kivity void test_long_jmp()
5777d36db35SAvi Kivity {
5787d36db35SAvi Kivity 	u32 esp[16];
5797d36db35SAvi Kivity 
58018253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
5814aa22949SAvi Kivity 	inregs.esp = (u32)(esp+16);
5827d36db35SAvi Kivity 	MK_INSN(long_jmp, "call 1f\n\t"
5837d36db35SAvi Kivity 			  "jmp 2f\n\t"
5847d36db35SAvi Kivity 			  "1: jmp $0, $test_function\n\t"
5857d36db35SAvi Kivity 		          "2:\n\t");
58618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_long_jmp);
5876055ea1fSAvi Kivity 	report("jmp far 1", R_AX, outregs.eax == 0x1234);
5887d36db35SAvi Kivity }
589fa74f8a6SMohammed Gamal 
5907d36db35SAvi Kivity void test_push_pop()
5917d36db35SAvi Kivity {
5927d36db35SAvi Kivity 	MK_INSN(push32, "mov $0x12345678, %eax\n\t"
5937d36db35SAvi Kivity 			"push %eax\n\t"
5947d36db35SAvi Kivity 			"pop %ebx\n\t");
5957d36db35SAvi Kivity 	MK_INSN(push16, "mov $0x1234, %ax\n\t"
5967d36db35SAvi Kivity 			"push %ax\n\t"
5977d36db35SAvi Kivity 			"pop %bx\n\t");
5987d36db35SAvi Kivity 
5997d36db35SAvi Kivity 	MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten
6007d36db35SAvi Kivity 			 "mov $0x123, %ax\n\t"
6017d36db35SAvi Kivity 			 "mov %ax, %es\n\t"
6027d36db35SAvi Kivity 			 "push %es\n\t"
6037d36db35SAvi Kivity 			 "pop %bx \n\t"
6047d36db35SAvi Kivity 			 );
6057d36db35SAvi Kivity 	MK_INSN(pop_es, "push %ax\n\t"
6067d36db35SAvi Kivity 			"pop %es\n\t"
6077d36db35SAvi Kivity 			"mov %es, %bx\n\t"
6087d36db35SAvi Kivity 			);
6097d36db35SAvi Kivity 	MK_INSN(push_pop_ss, "push %ss\n\t"
6107d36db35SAvi Kivity 			     "pushw %ax\n\t"
6117d36db35SAvi Kivity 			     "popw %ss\n\t"
6127d36db35SAvi Kivity 			     "mov %ss, %bx\n\t"
6137d36db35SAvi Kivity 			     "pop %ss\n\t"
6147d36db35SAvi Kivity 			);
6157d36db35SAvi Kivity 	MK_INSN(push_pop_fs, "push %fs\n\t"
6167d36db35SAvi Kivity 			     "pushl %eax\n\t"
6177d36db35SAvi Kivity 			     "popl %fs\n\t"
6187d36db35SAvi Kivity 			     "mov %fs, %ebx\n\t"
6197d36db35SAvi Kivity 			     "pop %fs\n\t"
6207d36db35SAvi Kivity 			);
62109b657b6SAvi Kivity 	MK_INSN(push_pop_high_esp_bits,
62209b657b6SAvi Kivity 		"xor $0x12340000, %esp \n\t"
62309b657b6SAvi Kivity 		"push %ax; \n\t"
62409b657b6SAvi Kivity 		"xor $0x12340000, %esp \n\t"
62509b657b6SAvi Kivity 		"pop %bx");
6267d36db35SAvi Kivity 
62718253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
62818253fdeSAvi Kivity 
62918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push32);
6306055ea1fSAvi Kivity 	report("push/pop 1", R_AX|R_BX,
6316055ea1fSAvi Kivity 	       outregs.eax == outregs.ebx && outregs.eax == 0x12345678);
6327d36db35SAvi Kivity 
63318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push16);
6346055ea1fSAvi Kivity 	report("push/pop 2", R_AX|R_BX,
6356055ea1fSAvi Kivity 	       outregs.eax == outregs.ebx && outregs.eax == 0x1234);
6367d36db35SAvi Kivity 
63718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push_es);
6386055ea1fSAvi Kivity 	report("push/pop 3", R_AX|R_BX,
6396055ea1fSAvi Kivity 	       outregs.ebx == outregs.eax && outregs.eax == 0x123);
6407d36db35SAvi Kivity 
64118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_pop_es);
6426055ea1fSAvi Kivity 	report("push/pop 4", R_AX|R_BX, outregs.ebx == outregs.eax);
6437d36db35SAvi Kivity 
64418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push_pop_ss);
6456055ea1fSAvi Kivity 	report("push/pop 5", R_AX|R_BX, outregs.ebx == outregs.eax);
6467d36db35SAvi Kivity 
64718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push_pop_fs);
6486055ea1fSAvi Kivity 	report("push/pop 6", R_AX|R_BX, outregs.ebx == outregs.eax);
64909b657b6SAvi Kivity 
65009b657b6SAvi Kivity 	inregs.eax = 0x9977;
65109b657b6SAvi Kivity 	inregs.ebx = 0x7799;
65209b657b6SAvi Kivity 	exec_in_big_real_mode(&insn_push_pop_high_esp_bits);
65309b657b6SAvi Kivity 	report("push/pop with high bits set in %esp", R_BX, outregs.ebx == 0x9977);
6547d36db35SAvi Kivity }
6557d36db35SAvi Kivity 
6567d36db35SAvi Kivity void test_null(void)
6577d36db35SAvi Kivity {
658d4dc402cSAvi Kivity 	MK_INSN(null, "");
659d4dc402cSAvi Kivity 
66018253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
66118253fdeSAvi Kivity 
66218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_null);
6636055ea1fSAvi Kivity 	report("null", 0, 1);
6647d36db35SAvi Kivity }
6657d36db35SAvi Kivity 
6667d36db35SAvi Kivity struct {
6677d36db35SAvi Kivity     char stack[500];
6687d36db35SAvi Kivity     char top[];
6697d36db35SAvi Kivity } tmp_stack;
6707d36db35SAvi Kivity 
6717d36db35SAvi Kivity void test_pusha_popa()
6727d36db35SAvi Kivity {
6737d36db35SAvi Kivity 	MK_INSN(pusha, "pusha\n\t"
6747d36db35SAvi Kivity 		       "pop %edi\n\t"
6757d36db35SAvi Kivity 		       "pop %esi\n\t"
6767d36db35SAvi Kivity 		       "pop %ebp\n\t"
6777d36db35SAvi Kivity 		       "add $4, %esp\n\t"
6787d36db35SAvi Kivity 		       "pop %ebx\n\t"
6797d36db35SAvi Kivity 		       "pop %edx\n\t"
6807d36db35SAvi Kivity 		       "pop %ecx\n\t"
6817d36db35SAvi Kivity 		       "pop %eax\n\t"
6827d36db35SAvi Kivity 		       );
6837d36db35SAvi Kivity 
6847d36db35SAvi Kivity 	MK_INSN(popa, "push %eax\n\t"
6857d36db35SAvi Kivity 		      "push %ecx\n\t"
6867d36db35SAvi Kivity 		      "push %edx\n\t"
6877d36db35SAvi Kivity 		      "push %ebx\n\t"
6887d36db35SAvi Kivity 		      "push %esp\n\t"
6897d36db35SAvi Kivity 		      "push %ebp\n\t"
6907d36db35SAvi Kivity 		      "push %esi\n\t"
6917d36db35SAvi Kivity 		      "push %edi\n\t"
6927d36db35SAvi Kivity 		      "popa\n\t"
6937d36db35SAvi Kivity 		      );
6947d36db35SAvi Kivity 
69518253fdeSAvi Kivity 	inregs = (struct regs){ .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = (unsigned long)&tmp_stack.top };
6967d36db35SAvi Kivity 
69718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_pusha);
6986055ea1fSAvi Kivity 	report("pusha/popa 1", 0, 1);
69918253fdeSAvi Kivity 
70018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_popa);
7016055ea1fSAvi Kivity 	report("pusha/popa 1", 0, 1);
7027d36db35SAvi Kivity }
7037d36db35SAvi Kivity 
7047d36db35SAvi Kivity void test_iret()
7057d36db35SAvi Kivity {
7067d36db35SAvi Kivity 	MK_INSN(iret32, "pushf\n\t"
7077d36db35SAvi Kivity 			"pushl %cs\n\t"
7087d36db35SAvi Kivity 			"call 1f\n\t" /* a near call will push eip onto the stack */
7097d36db35SAvi Kivity 			"jmp 2f\n\t"
7107d36db35SAvi Kivity 			"1: iret\n\t"
7117d36db35SAvi Kivity 			"2:\n\t"
7127d36db35SAvi Kivity 		     );
7137d36db35SAvi Kivity 
7147d36db35SAvi Kivity 	MK_INSN(iret16, "pushfw\n\t"
7157d36db35SAvi Kivity 			"pushw %cs\n\t"
7167d36db35SAvi Kivity 			"callw 1f\n\t"
7177d36db35SAvi Kivity 			"jmp 2f\n\t"
7187d36db35SAvi Kivity 			"1: iretw\n\t"
7197d36db35SAvi Kivity 			"2:\n\t");
7207d36db35SAvi Kivity 
7217d36db35SAvi Kivity 	MK_INSN(iret_flags32, "pushfl\n\t"
7227d36db35SAvi Kivity 			      "popl %eax\n\t"
7237d36db35SAvi Kivity 			      "andl $~0x2, %eax\n\t"
7247d36db35SAvi Kivity 			      "orl $0xffc08028, %eax\n\t"
7257d36db35SAvi Kivity 			      "pushl %eax\n\t"
7267d36db35SAvi Kivity 			      "pushl %cs\n\t"
7277d36db35SAvi Kivity 			      "call 1f\n\t"
7287d36db35SAvi Kivity 			      "jmp 2f\n\t"
7297d36db35SAvi Kivity 			      "1: iret\n\t"
7307d36db35SAvi Kivity 			      "2:\n\t");
7317d36db35SAvi Kivity 
7327d36db35SAvi Kivity 	MK_INSN(iret_flags16, "pushfw\n\t"
7337d36db35SAvi Kivity 			      "popw %ax\n\t"
7347d36db35SAvi Kivity 			      "and $~0x2, %ax\n\t"
7357d36db35SAvi Kivity 			      "or $0x8028, %ax\n\t"
7367d36db35SAvi Kivity 			      "pushw %ax\n\t"
7377d36db35SAvi Kivity 			      "pushw %cs\n\t"
7387d36db35SAvi Kivity 			      "callw 1f\n\t"
7397d36db35SAvi Kivity 			      "jmp 2f\n\t"
7407d36db35SAvi Kivity 			      "1: iretw\n\t"
7417d36db35SAvi Kivity 			      "2:\n\t");
7427d36db35SAvi Kivity 
74318253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
7447d36db35SAvi Kivity 
74518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_iret32);
7466055ea1fSAvi Kivity 	report("iret 1", 0, 1);
7477d36db35SAvi Kivity 
74818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_iret16);
7496055ea1fSAvi Kivity 	report("iret 2", 0, 1);
7507d36db35SAvi Kivity 
75118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_iret_flags32);
7526055ea1fSAvi Kivity 	report("iret 3", R_AX, 1);
75318253fdeSAvi Kivity 
75418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_iret_flags16);
7556055ea1fSAvi Kivity 	report("iret 4", R_AX, 1);
7567d36db35SAvi Kivity }
7577d36db35SAvi Kivity 
75896b9ca1eSMohammed Gamal void test_int()
75996b9ca1eSMohammed Gamal {
76018253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
76196b9ca1eSMohammed Gamal 
76296b9ca1eSMohammed Gamal 	*(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */
76396b9ca1eSMohammed Gamal 	*(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */
76496b9ca1eSMohammed Gamal 
76596b9ca1eSMohammed Gamal 	MK_INSN(int11, "int $0x11\n\t");
76696b9ca1eSMohammed Gamal 
76718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_int11);
7686055ea1fSAvi Kivity 	report("int 1", 0, 1);
76996b9ca1eSMohammed Gamal }
77096b9ca1eSMohammed Gamal 
771fa74f8a6SMohammed Gamal void test_imul()
772fa74f8a6SMohammed Gamal {
773fa74f8a6SMohammed Gamal 	MK_INSN(imul8_1, "mov $2, %al\n\t"
774fa74f8a6SMohammed Gamal 			"mov $-4, %cx\n\t"
775fa74f8a6SMohammed Gamal 			"imul %cl\n\t");
776fa74f8a6SMohammed Gamal 
777fa74f8a6SMohammed Gamal 	MK_INSN(imul16_1, "mov $2, %ax\n\t"
778fa74f8a6SMohammed Gamal 		      "mov $-4, %cx\n\t"
779fa74f8a6SMohammed Gamal 		      "imul %cx\n\t");
780fa74f8a6SMohammed Gamal 
781fa74f8a6SMohammed Gamal 	MK_INSN(imul32_1, "mov $2, %eax\n\t"
782fa74f8a6SMohammed Gamal 		       "mov $-4, %ecx\n\t"
783fa74f8a6SMohammed Gamal 		       "imul %ecx\n\t");
784fa74f8a6SMohammed Gamal 
785fa74f8a6SMohammed Gamal 	MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t"
786fa74f8a6SMohammed Gamal 			"mov $4, %cx\n\t"
787fa74f8a6SMohammed Gamal 			"imul %cl\n\t");
788fa74f8a6SMohammed Gamal 
789fa74f8a6SMohammed Gamal 	MK_INSN(imul16_2, "mov $2, %ax\n\t"
790fa74f8a6SMohammed Gamal 			"mov $4, %cx\n\t"
791fa74f8a6SMohammed Gamal 			"imul %cx\n\t");
792fa74f8a6SMohammed Gamal 
793fa74f8a6SMohammed Gamal 	MK_INSN(imul32_2, "mov $2, %eax\n\t"
794fa74f8a6SMohammed Gamal 			"mov $4, %ecx\n\t"
795fa74f8a6SMohammed Gamal 			"imul %ecx\n\t");
796fa74f8a6SMohammed Gamal 
79718253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
79818253fdeSAvi Kivity 
79918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul8_1);
8006055ea1fSAvi Kivity 	report("imul 1", R_AX | R_CX | R_DX, (outregs.eax & 0xff) == (u8)-8);
801fa74f8a6SMohammed Gamal 
80218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul16_1);
8036055ea1fSAvi Kivity 	report("imul 2", R_AX | R_CX | R_DX, outregs.eax == (u16)-8);
804fa74f8a6SMohammed Gamal 
80518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul32_1);
8066055ea1fSAvi Kivity 	report("imul 3", R_AX | R_CX | R_DX, outregs.eax == (u32)-8);
807fa74f8a6SMohammed Gamal 
80818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul8_2);
8096055ea1fSAvi Kivity 	report("imul 4", R_AX | R_CX | R_DX,
8106055ea1fSAvi Kivity 	       (outregs.eax & 0xffff) == 8
81181050840SAvi Kivity 	       && (outregs.eax & 0xffff0000) == 0x12340000);
812fa74f8a6SMohammed Gamal 
81318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul16_2);
8146055ea1fSAvi Kivity 	report("imul 5", R_AX | R_CX | R_DX, outregs.eax == 8);
815fa74f8a6SMohammed Gamal 
81618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul32_2);
8176055ea1fSAvi Kivity 	report("imul 6", R_AX | R_CX | R_DX, outregs.eax == 8);
818fa74f8a6SMohammed Gamal }
819fa74f8a6SMohammed Gamal 
82059317bd1SMohammed Gamal void test_mul()
82159317bd1SMohammed Gamal {
82259317bd1SMohammed Gamal 	MK_INSN(mul8, "mov $2, %al\n\t"
82359317bd1SMohammed Gamal 			"mov $4, %cx\n\t"
82459317bd1SMohammed Gamal 			"imul %cl\n\t");
82559317bd1SMohammed Gamal 
82659317bd1SMohammed Gamal 	MK_INSN(mul16, "mov $2, %ax\n\t"
82759317bd1SMohammed Gamal 			"mov $4, %cx\n\t"
82859317bd1SMohammed Gamal 			"imul %cx\n\t");
82959317bd1SMohammed Gamal 
83059317bd1SMohammed Gamal 	MK_INSN(mul32, "mov $2, %eax\n\t"
83159317bd1SMohammed Gamal 			"mov $4, %ecx\n\t"
83259317bd1SMohammed Gamal 			"imul %ecx\n\t");
83359317bd1SMohammed Gamal 
83418253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
83518253fdeSAvi Kivity 
83618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mul8);
8376055ea1fSAvi Kivity 	report("mul 1", R_AX | R_CX | R_DX, (outregs.eax & 0xff) == 8);
83859317bd1SMohammed Gamal 
83918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mul16);
8406055ea1fSAvi Kivity 	report("mul 2", R_AX | R_CX | R_DX, outregs.eax == 8);
84159317bd1SMohammed Gamal 
84218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mul32);
8436055ea1fSAvi Kivity 	report("mul 3", R_AX | R_CX | R_DX, outregs.eax == 8);
84459317bd1SMohammed Gamal }
84559317bd1SMohammed Gamal 
8460d4c7614SMohammed Gamal void test_div()
8470d4c7614SMohammed Gamal {
8480d4c7614SMohammed Gamal 	MK_INSN(div8, "mov $257, %ax\n\t"
8490d4c7614SMohammed Gamal 			"mov $2, %cl\n\t"
8500d4c7614SMohammed Gamal 			"div %cl\n\t");
8510d4c7614SMohammed Gamal 
8520d4c7614SMohammed Gamal 	MK_INSN(div16, "mov $512, %ax\n\t"
8530d4c7614SMohammed Gamal 			"mov $5, %cx\n\t"
8540d4c7614SMohammed Gamal 			"div %cx\n\t");
8550d4c7614SMohammed Gamal 
8560d4c7614SMohammed Gamal 	MK_INSN(div32, "mov $512, %eax\n\t"
8570d4c7614SMohammed Gamal 			"mov $5, %ecx\n\t"
8580d4c7614SMohammed Gamal 			"div %ecx\n\t");
8590d4c7614SMohammed Gamal 
86018253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
86118253fdeSAvi Kivity 
86218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_div8);
8636055ea1fSAvi Kivity 	report("div 1", R_AX | R_CX | R_DX, outregs.eax == 384);
8640d4c7614SMohammed Gamal 
86518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_div16);
8666055ea1fSAvi Kivity 	report("div 2", R_AX | R_CX | R_DX,
8676055ea1fSAvi Kivity 	       outregs.eax == 102 && outregs.edx == 2);
8680d4c7614SMohammed Gamal 
86918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_div32);
8706055ea1fSAvi Kivity 	report("div 3", R_AX | R_CX | R_DX,
8716055ea1fSAvi Kivity 	       outregs.eax == 102 && outregs.edx == 2);
8720d4c7614SMohammed Gamal }
8730d4c7614SMohammed Gamal 
8740d4c7614SMohammed Gamal void test_idiv()
8750d4c7614SMohammed Gamal {
8760d4c7614SMohammed Gamal 	MK_INSN(idiv8, "mov $256, %ax\n\t"
8770d4c7614SMohammed Gamal 			"mov $-2, %cl\n\t"
8780d4c7614SMohammed Gamal 			"idiv %cl\n\t");
8790d4c7614SMohammed Gamal 
8800d4c7614SMohammed Gamal 	MK_INSN(idiv16, "mov $512, %ax\n\t"
8810d4c7614SMohammed Gamal 			"mov $-2, %cx\n\t"
8820d4c7614SMohammed Gamal 			"idiv %cx\n\t");
8830d4c7614SMohammed Gamal 
8840d4c7614SMohammed Gamal 	MK_INSN(idiv32, "mov $512, %eax\n\t"
8850d4c7614SMohammed Gamal 			"mov $-2, %ecx\n\t"
8860d4c7614SMohammed Gamal 			"idiv %ecx\n\t");
8870d4c7614SMohammed Gamal 
88818253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
88918253fdeSAvi Kivity 
89018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_idiv8);
8916055ea1fSAvi Kivity 	report("idiv 1", R_AX | R_CX | R_DX, outregs.eax == (u8)-128);
8920d4c7614SMohammed Gamal 
89318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_idiv16);
8946055ea1fSAvi Kivity 	report("idiv 2", R_AX | R_CX | R_DX, outregs.eax == (u16)-256);
8950d4c7614SMohammed Gamal 
89618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_idiv32);
8976055ea1fSAvi Kivity 	report("idiv 3", R_AX | R_CX | R_DX, outregs.eax == (u32)-256);
8980d4c7614SMohammed Gamal }
8990d4c7614SMohammed Gamal 
9006e293cf5SWei Yongjun void test_cbw(void)
9016e293cf5SWei Yongjun {
9026e293cf5SWei Yongjun 	MK_INSN(cbw, "mov $0xFE, %eax \n\t"
9036e293cf5SWei Yongjun 		     "cbw\n\t");
9046e293cf5SWei Yongjun 	MK_INSN(cwde, "mov $0xFFFE, %eax \n\t"
9056e293cf5SWei Yongjun 		      "cwde\n\t");
9066e293cf5SWei Yongjun 
90718253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
90818253fdeSAvi Kivity 
90918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cbw);
9106055ea1fSAvi Kivity 	report("cbq 1", ~0, outregs.eax == 0xFFFE);
9116e293cf5SWei Yongjun 
91218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cwde);
9136055ea1fSAvi Kivity 	report("cwde 1", ~0, outregs.eax == 0xFFFFFFFE);
9146e293cf5SWei Yongjun }
9156e293cf5SWei Yongjun 
916eacef4e2SWei Yongjun void test_loopcc(void)
917eacef4e2SWei Yongjun {
918eacef4e2SWei Yongjun 	MK_INSN(loop, "mov $10, %ecx\n\t"
919eacef4e2SWei Yongjun 		      "1: inc %eax\n\t"
920eacef4e2SWei Yongjun 		      "loop 1b\n\t");
921eacef4e2SWei Yongjun 
922eacef4e2SWei Yongjun 	MK_INSN(loope, "mov $10, %ecx\n\t"
923eacef4e2SWei Yongjun 		       "mov $1, %eax\n\t"
924eacef4e2SWei Yongjun 		       "1: dec %eax\n\t"
925eacef4e2SWei Yongjun 		       "loope 1b\n\t");
926eacef4e2SWei Yongjun 
927eacef4e2SWei Yongjun 	MK_INSN(loopne, "mov $10, %ecx\n\t"
928eacef4e2SWei Yongjun 		        "mov $5, %eax\n\t"
929eacef4e2SWei Yongjun 		        "1: dec %eax\n\t"
930eacef4e2SWei Yongjun 			"loopne 1b\n\t");
931eacef4e2SWei Yongjun 
93218253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
933eacef4e2SWei Yongjun 
93418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_loop);
9356055ea1fSAvi Kivity 	report("LOOPcc short 1", R_AX, outregs.eax == 10);
93618253fdeSAvi Kivity 
93718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_loope);
9386055ea1fSAvi Kivity 	report("LOOPcc short 2", R_AX | R_CX,
9396055ea1fSAvi Kivity 	       outregs.eax == -1 && outregs.ecx == 8);
940eacef4e2SWei Yongjun 
94118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_loopne);
9426055ea1fSAvi Kivity 	report("LOOPcc short 3", R_AX | R_CX,
9436055ea1fSAvi Kivity 	       outregs.eax == 0 && outregs.ecx == 5);
944eacef4e2SWei Yongjun }
945eacef4e2SWei Yongjun 
946b274feedSAvi Kivity static void test_das(void)
947b274feedSAvi Kivity {
948b274feedSAvi Kivity     short i;
94981050840SAvi Kivity     u16 nr_fail = 0;
950b274feedSAvi Kivity     static unsigned test_cases[1024] = {
951b274feedSAvi Kivity         0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00,
952b274feedSAvi Kivity         0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01,
953b274feedSAvi Kivity         0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02,
954b274feedSAvi Kivity         0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03,
955b274feedSAvi Kivity         0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04,
956b274feedSAvi Kivity         0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05,
957b274feedSAvi Kivity         0x06000606, 0x8701a606, 0x56100006, 0x9711a006,
958b274feedSAvi Kivity         0x02000707, 0x8301a707, 0x12100107, 0x9311a107,
959b274feedSAvi Kivity         0x02000808, 0x8301a808, 0x12100208, 0x9311a208,
960b274feedSAvi Kivity         0x06000909, 0x8701a909, 0x16100309, 0x9711a309,
961b274feedSAvi Kivity         0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a,
962b274feedSAvi Kivity         0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b,
963b274feedSAvi Kivity         0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c,
964b274feedSAvi Kivity         0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d,
965b274feedSAvi Kivity         0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e,
966b274feedSAvi Kivity         0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f,
967b274feedSAvi Kivity         0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10,
968b274feedSAvi Kivity         0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11,
969b274feedSAvi Kivity         0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12,
970b274feedSAvi Kivity         0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13,
971b274feedSAvi Kivity         0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14,
972b274feedSAvi Kivity         0x02001515, 0x8301b515, 0x16100f15, 0x9711af15,
973b274feedSAvi Kivity         0x02001616, 0x8301b616, 0x12101016, 0x9311b016,
974b274feedSAvi Kivity         0x06001717, 0x8701b717, 0x16101117, 0x9711b117,
975b274feedSAvi Kivity         0x06001818, 0x8701b818, 0x16101218, 0x9711b218,
976b274feedSAvi Kivity         0x02001919, 0x8301b919, 0x12101319, 0x9311b319,
977b274feedSAvi Kivity         0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a,
978b274feedSAvi Kivity         0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b,
979b274feedSAvi Kivity         0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c,
980b274feedSAvi Kivity         0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d,
981b274feedSAvi Kivity         0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e,
982b274feedSAvi Kivity         0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f,
983b274feedSAvi Kivity         0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20,
984b274feedSAvi Kivity         0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21,
985b274feedSAvi Kivity         0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22,
986b274feedSAvi Kivity         0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23,
987b274feedSAvi Kivity         0x06002424, 0x8301c424, 0x16101e24, 0x9711be24,
988b274feedSAvi Kivity         0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25,
989b274feedSAvi Kivity         0x02002626, 0x8701c626, 0x12102026, 0x9711c026,
990b274feedSAvi Kivity         0x06002727, 0x8301c727, 0x16102127, 0x9311c127,
991b274feedSAvi Kivity         0x06002828, 0x8301c828, 0x16102228, 0x9311c228,
992b274feedSAvi Kivity         0x02002929, 0x8701c929, 0x12102329, 0x9711c329,
993b274feedSAvi Kivity         0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a,
994b274feedSAvi Kivity         0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b,
995b274feedSAvi Kivity         0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c,
996b274feedSAvi Kivity         0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d,
997b274feedSAvi Kivity         0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e,
998b274feedSAvi Kivity         0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f,
999b274feedSAvi Kivity         0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30,
1000b274feedSAvi Kivity         0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31,
1001b274feedSAvi Kivity         0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32,
1002b274feedSAvi Kivity         0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33,
1003b274feedSAvi Kivity         0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34,
1004b274feedSAvi Kivity         0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35,
1005b274feedSAvi Kivity         0x06003636, 0x8301d636, 0x16103036, 0x9311d036,
1006b274feedSAvi Kivity         0x02003737, 0x8701d737, 0x12103137, 0x9711d137,
1007b274feedSAvi Kivity         0x02003838, 0x8701d838, 0x12103238, 0x9711d238,
1008b274feedSAvi Kivity         0x06003939, 0x8301d939, 0x16103339, 0x9311d339,
1009b274feedSAvi Kivity         0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a,
1010b274feedSAvi Kivity         0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b,
1011b274feedSAvi Kivity         0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c,
1012b274feedSAvi Kivity         0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d,
1013b274feedSAvi Kivity         0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e,
1014b274feedSAvi Kivity         0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f,
1015b274feedSAvi Kivity         0x02004040, 0x8301e040, 0x16103a40, 0x9311da40,
1016b274feedSAvi Kivity         0x06004141, 0x8701e141, 0x12103b41, 0x9711db41,
1017b274feedSAvi Kivity         0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42,
1018b274feedSAvi Kivity         0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43,
1019b274feedSAvi Kivity         0x06004444, 0x8701e444, 0x12103e44, 0x9711de44,
1020b274feedSAvi Kivity         0x02004545, 0x8301e545, 0x16103f45, 0x9311df45,
1021b274feedSAvi Kivity         0x02004646, 0x8301e646, 0x12104046, 0x9311e046,
1022b274feedSAvi Kivity         0x06004747, 0x8701e747, 0x16104147, 0x9711e147,
1023b274feedSAvi Kivity         0x06004848, 0x8701e848, 0x16104248, 0x9711e248,
1024b274feedSAvi Kivity         0x02004949, 0x8301e949, 0x12104349, 0x9311e349,
1025b274feedSAvi Kivity         0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a,
1026b274feedSAvi Kivity         0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b,
1027b274feedSAvi Kivity         0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c,
1028b274feedSAvi Kivity         0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d,
1029b274feedSAvi Kivity         0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e,
1030b274feedSAvi Kivity         0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f,
1031b274feedSAvi Kivity         0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50,
1032b274feedSAvi Kivity         0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51,
1033b274feedSAvi Kivity         0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52,
1034b274feedSAvi Kivity         0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53,
1035b274feedSAvi Kivity         0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54,
1036b274feedSAvi Kivity         0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55,
1037b274feedSAvi Kivity         0x06005656, 0x8701f656, 0x16105056, 0x9711f056,
1038b274feedSAvi Kivity         0x02005757, 0x8301f757, 0x12105157, 0x9311f157,
1039b274feedSAvi Kivity         0x02005858, 0x8301f858, 0x12105258, 0x9311f258,
1040b274feedSAvi Kivity         0x06005959, 0x8701f959, 0x16105359, 0x9711f359,
1041b274feedSAvi Kivity         0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a,
1042b274feedSAvi Kivity         0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b,
1043b274feedSAvi Kivity         0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c,
1044b274feedSAvi Kivity         0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d,
1045b274feedSAvi Kivity         0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e,
1046b274feedSAvi Kivity         0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f,
1047b274feedSAvi Kivity         0x06006060, 0x47010060, 0x16105a60, 0x9711fa60,
1048b274feedSAvi Kivity         0x02006161, 0x03010161, 0x12105b61, 0x9311fb61,
1049b274feedSAvi Kivity         0x02006262, 0x03010262, 0x16105c62, 0x9711fc62,
1050b274feedSAvi Kivity         0x06006363, 0x07010363, 0x12105d63, 0x9311fd63,
1051b274feedSAvi Kivity         0x02006464, 0x03010464, 0x12105e64, 0x9311fe64,
1052b274feedSAvi Kivity         0x06006565, 0x07010565, 0x16105f65, 0x9711ff65,
1053b274feedSAvi Kivity         0x06006666, 0x07010666, 0x16106066, 0x57110066,
1054b274feedSAvi Kivity         0x02006767, 0x03010767, 0x12106167, 0x13110167,
1055b274feedSAvi Kivity         0x02006868, 0x03010868, 0x12106268, 0x13110268,
1056b274feedSAvi Kivity         0x06006969, 0x07010969, 0x16106369, 0x17110369,
1057b274feedSAvi Kivity         0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a,
1058b274feedSAvi Kivity         0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b,
1059b274feedSAvi Kivity         0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c,
1060b274feedSAvi Kivity         0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d,
1061b274feedSAvi Kivity         0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e,
1062b274feedSAvi Kivity         0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f,
1063b274feedSAvi Kivity         0x02007070, 0x03011070, 0x16106a70, 0x17110a70,
1064b274feedSAvi Kivity         0x06007171, 0x07011171, 0x12106b71, 0x13110b71,
1065b274feedSAvi Kivity         0x06007272, 0x07011272, 0x16106c72, 0x17110c72,
1066b274feedSAvi Kivity         0x02007373, 0x03011373, 0x12106d73, 0x13110d73,
1067b274feedSAvi Kivity         0x06007474, 0x07011474, 0x12106e74, 0x13110e74,
1068b274feedSAvi Kivity         0x02007575, 0x03011575, 0x16106f75, 0x17110f75,
1069b274feedSAvi Kivity         0x02007676, 0x03011676, 0x12107076, 0x13111076,
1070b274feedSAvi Kivity         0x06007777, 0x07011777, 0x16107177, 0x17111177,
1071b274feedSAvi Kivity         0x06007878, 0x07011878, 0x16107278, 0x17111278,
1072b274feedSAvi Kivity         0x02007979, 0x03011979, 0x12107379, 0x13111379,
1073b274feedSAvi Kivity         0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a,
1074b274feedSAvi Kivity         0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b,
1075b274feedSAvi Kivity         0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c,
1076b274feedSAvi Kivity         0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d,
1077b274feedSAvi Kivity         0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e,
1078b274feedSAvi Kivity         0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f,
1079b274feedSAvi Kivity         0x82008080, 0x03012080, 0x12107a80, 0x13111a80,
1080b274feedSAvi Kivity         0x86008181, 0x07012181, 0x16107b81, 0x17111b81,
1081b274feedSAvi Kivity         0x86008282, 0x07012282, 0x12107c82, 0x13111c82,
1082b274feedSAvi Kivity         0x82008383, 0x03012383, 0x16107d83, 0x17111d83,
1083b274feedSAvi Kivity         0x86008484, 0x07012484, 0x16107e84, 0x17111e84,
1084b274feedSAvi Kivity         0x82008585, 0x03012585, 0x12107f85, 0x13111f85,
1085b274feedSAvi Kivity         0x82008686, 0x03012686, 0x92108086, 0x13112086,
1086b274feedSAvi Kivity         0x86008787, 0x07012787, 0x96108187, 0x17112187,
1087b274feedSAvi Kivity         0x86008888, 0x07012888, 0x96108288, 0x17112288,
1088b274feedSAvi Kivity         0x82008989, 0x03012989, 0x92108389, 0x13112389,
1089b274feedSAvi Kivity         0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a,
1090b274feedSAvi Kivity         0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b,
1091b274feedSAvi Kivity         0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c,
1092b274feedSAvi Kivity         0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d,
1093b274feedSAvi Kivity         0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e,
1094b274feedSAvi Kivity         0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f,
1095b274feedSAvi Kivity         0x86009090, 0x07013090, 0x92108a90, 0x13112a90,
1096b274feedSAvi Kivity         0x82009191, 0x03013191, 0x96108b91, 0x17112b91,
1097b274feedSAvi Kivity         0x82009292, 0x03013292, 0x92108c92, 0x13112c92,
1098b274feedSAvi Kivity         0x86009393, 0x07013393, 0x96108d93, 0x17112d93,
1099b274feedSAvi Kivity         0x82009494, 0x03013494, 0x96108e94, 0x17112e94,
1100b274feedSAvi Kivity         0x86009595, 0x07013595, 0x92108f95, 0x13112f95,
1101b274feedSAvi Kivity         0x86009696, 0x07013696, 0x96109096, 0x17113096,
1102b274feedSAvi Kivity         0x82009797, 0x03013797, 0x92109197, 0x13113197,
1103b274feedSAvi Kivity         0x82009898, 0x03013898, 0x92109298, 0x13113298,
1104b274feedSAvi Kivity         0x86009999, 0x07013999, 0x96109399, 0x17113399,
1105b274feedSAvi Kivity         0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a,
1106b274feedSAvi Kivity         0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b,
1107b274feedSAvi Kivity         0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c,
1108b274feedSAvi Kivity         0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d,
1109b274feedSAvi Kivity         0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e,
1110b274feedSAvi Kivity         0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f,
1111b274feedSAvi Kivity         0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0,
1112b274feedSAvi Kivity         0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1,
1113b274feedSAvi Kivity         0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2,
1114b274feedSAvi Kivity         0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3,
1115b274feedSAvi Kivity         0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4,
1116b274feedSAvi Kivity         0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5,
1117b274feedSAvi Kivity         0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6,
1118b274feedSAvi Kivity         0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7,
1119b274feedSAvi Kivity         0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8,
1120b274feedSAvi Kivity         0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9,
1121b274feedSAvi Kivity         0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa,
1122b274feedSAvi Kivity         0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab,
1123b274feedSAvi Kivity         0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac,
1124b274feedSAvi Kivity         0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad,
1125b274feedSAvi Kivity         0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae,
1126b274feedSAvi Kivity         0x130049af, 0x130149af, 0x131049af, 0x131149af,
1127b274feedSAvi Kivity         0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0,
1128b274feedSAvi Kivity         0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1,
1129b274feedSAvi Kivity         0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2,
1130b274feedSAvi Kivity         0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3,
1131b274feedSAvi Kivity         0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4,
1132b274feedSAvi Kivity         0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5,
1133b274feedSAvi Kivity         0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6,
1134b274feedSAvi Kivity         0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7,
1135b274feedSAvi Kivity         0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8,
1136b274feedSAvi Kivity         0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9,
1137b274feedSAvi Kivity         0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba,
1138b274feedSAvi Kivity         0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb,
1139b274feedSAvi Kivity         0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc,
1140b274feedSAvi Kivity         0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd,
1141b274feedSAvi Kivity         0x130058be, 0x130158be, 0x131058be, 0x131158be,
1142b274feedSAvi Kivity         0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf,
1143b274feedSAvi Kivity         0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0,
1144b274feedSAvi Kivity         0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1,
1145b274feedSAvi Kivity         0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2,
1146b274feedSAvi Kivity         0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3,
1147b274feedSAvi Kivity         0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4,
1148b274feedSAvi Kivity         0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5,
1149b274feedSAvi Kivity         0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6,
1150b274feedSAvi Kivity         0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7,
1151b274feedSAvi Kivity         0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8,
1152b274feedSAvi Kivity         0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9,
1153b274feedSAvi Kivity         0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca,
1154b274feedSAvi Kivity         0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb,
1155b274feedSAvi Kivity         0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc,
1156b274feedSAvi Kivity         0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd,
1157b274feedSAvi Kivity         0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce,
1158b274feedSAvi Kivity         0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf,
1159b274feedSAvi Kivity         0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0,
1160b274feedSAvi Kivity         0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1,
1161b274feedSAvi Kivity         0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2,
1162b274feedSAvi Kivity         0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3,
1163b274feedSAvi Kivity         0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4,
1164b274feedSAvi Kivity         0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5,
1165b274feedSAvi Kivity         0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6,
1166b274feedSAvi Kivity         0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7,
1167b274feedSAvi Kivity         0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8,
1168b274feedSAvi Kivity         0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9,
1169b274feedSAvi Kivity         0x170074da, 0x170174da, 0x171074da, 0x171174da,
1170b274feedSAvi Kivity         0x130075db, 0x130175db, 0x131075db, 0x131175db,
1171b274feedSAvi Kivity         0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc,
1172b274feedSAvi Kivity         0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd,
1173b274feedSAvi Kivity         0x170078de, 0x170178de, 0x171078de, 0x171178de,
1174b274feedSAvi Kivity         0x130079df, 0x130179df, 0x131079df, 0x131179df,
1175b274feedSAvi Kivity         0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0,
1176b274feedSAvi Kivity         0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1,
1177b274feedSAvi Kivity         0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2,
1178b274feedSAvi Kivity         0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3,
1179b274feedSAvi Kivity         0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4,
1180b274feedSAvi Kivity         0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5,
1181b274feedSAvi Kivity         0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6,
1182b274feedSAvi Kivity         0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7,
1183b274feedSAvi Kivity         0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8,
1184b274feedSAvi Kivity         0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9,
1185b274feedSAvi Kivity         0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea,
1186b274feedSAvi Kivity         0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb,
1187b274feedSAvi Kivity         0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec,
1188b274feedSAvi Kivity         0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed,
1189b274feedSAvi Kivity         0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee,
1190b274feedSAvi Kivity         0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef,
1191b274feedSAvi Kivity         0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0,
1192b274feedSAvi Kivity         0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1,
1193b274feedSAvi Kivity         0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2,
1194b274feedSAvi Kivity         0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3,
1195b274feedSAvi Kivity         0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4,
1196b274feedSAvi Kivity         0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5,
1197b274feedSAvi Kivity         0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6,
1198b274feedSAvi Kivity         0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7,
1199b274feedSAvi Kivity         0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8,
1200b274feedSAvi Kivity         0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9,
1201b274feedSAvi Kivity         0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa,
1202b274feedSAvi Kivity         0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb,
1203b274feedSAvi Kivity         0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc,
1204b274feedSAvi Kivity         0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd,
1205b274feedSAvi Kivity         0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe,
1206b274feedSAvi Kivity         0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff,
1207b274feedSAvi Kivity     };
1208b274feedSAvi Kivity 
1209b274feedSAvi Kivity     MK_INSN(das, "das");
1210b274feedSAvi Kivity 
121118253fdeSAvi Kivity     inregs = (struct regs){ 0 };
121218253fdeSAvi Kivity 
1213b274feedSAvi Kivity     for (i = 0; i < 1024; ++i) {
1214b274feedSAvi Kivity         unsigned tmp = test_cases[i];
1215b274feedSAvi Kivity         inregs.eax = tmp & 0xff;
1216b274feedSAvi Kivity         inregs.eflags = (tmp >> 16) & 0xff;
121718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_das);
121818253fdeSAvi Kivity 	if (!regs_equal(R_AX)
1219b274feedSAvi Kivity             || outregs.eax != ((tmp >> 8) & 0xff)
1220b274feedSAvi Kivity             || (outregs.eflags & 0xff) != (tmp >> 24)) {
122181050840SAvi Kivity 	    ++nr_fail;
122281050840SAvi Kivity 	    break;
1223b274feedSAvi Kivity         }
1224b274feedSAvi Kivity     }
12256055ea1fSAvi Kivity     report("DAS", ~0, nr_fail == 0);
1226b274feedSAvi Kivity }
1227b274feedSAvi Kivity 
12280cbd5b06SMohammed Gamal void test_cwd_cdq()
12290cbd5b06SMohammed Gamal {
12300cbd5b06SMohammed Gamal 	/* Sign-bit set */
12310cbd5b06SMohammed Gamal 	MK_INSN(cwd_1, "mov $0x8000, %ax\n\t"
12320cbd5b06SMohammed Gamal 		       "cwd\n\t");
12330cbd5b06SMohammed Gamal 
12340cbd5b06SMohammed Gamal 	/* Sign-bit not set */
12350cbd5b06SMohammed Gamal 	MK_INSN(cwd_2, "mov $0x1000, %ax\n\t"
12360cbd5b06SMohammed Gamal 		       "cwd\n\t");
12370cbd5b06SMohammed Gamal 
12380cbd5b06SMohammed Gamal 	/* Sign-bit set */
12390cbd5b06SMohammed Gamal 	MK_INSN(cdq_1, "mov $0x80000000, %eax\n\t"
12400cbd5b06SMohammed Gamal 		       "cdq\n\t");
12410cbd5b06SMohammed Gamal 
12420cbd5b06SMohammed Gamal 	/* Sign-bit not set */
12430cbd5b06SMohammed Gamal 	MK_INSN(cdq_2, "mov $0x10000000, %eax\n\t"
12440cbd5b06SMohammed Gamal 		       "cdq\n\t");
12450cbd5b06SMohammed Gamal 
124618253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
124718253fdeSAvi Kivity 
124818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cwd_1);
12496055ea1fSAvi Kivity 	report("cwd 1", R_AX | R_DX,
12506055ea1fSAvi Kivity 	       outregs.eax == 0x8000 && outregs.edx == 0xffff);
12510cbd5b06SMohammed Gamal 
125218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cwd_2);
12536055ea1fSAvi Kivity 	report("cwd 2", R_AX | R_DX,
12546055ea1fSAvi Kivity 	       outregs.eax == 0x1000 && outregs.edx == 0);
12550cbd5b06SMohammed Gamal 
125618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cdq_1);
12576055ea1fSAvi Kivity 	report("cdq 1", R_AX | R_DX,
12586055ea1fSAvi Kivity 	       outregs.eax == 0x80000000 && outregs.edx == 0xffffffff);
12590cbd5b06SMohammed Gamal 
126018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cdq_2);
12616055ea1fSAvi Kivity 	report("cdq 2", R_AX | R_DX,
12626055ea1fSAvi Kivity 	       outregs.eax == 0x10000000 && outregs.edx == 0);
12630cbd5b06SMohammed Gamal }
12640cbd5b06SMohammed Gamal 
126537f51a4aSWei Yongjun static struct {
126637f51a4aSWei Yongjun         void *address;
126737f51a4aSWei Yongjun         unsigned short sel;
126837f51a4aSWei Yongjun } __attribute__((packed)) desc = {
126937f51a4aSWei Yongjun 	(void *)0x1234,
127037f51a4aSWei Yongjun 	0x10,
127137f51a4aSWei Yongjun };
127237f51a4aSWei Yongjun 
127337f51a4aSWei Yongjun void test_lds_lss()
127437f51a4aSWei Yongjun {
127537f51a4aSWei Yongjun 	inregs = (struct regs){ .ebx = (unsigned long)&desc };
127637f51a4aSWei Yongjun 
127737f51a4aSWei Yongjun 	MK_INSN(lds, "push %ds\n\t"
127837f51a4aSWei Yongjun 		     "lds (%ebx), %eax\n\t"
127937f51a4aSWei Yongjun 		     "mov %ds, %ebx\n\t"
128037f51a4aSWei Yongjun 		     "pop %ds\n\t");
128137f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_lds);
128237f51a4aSWei Yongjun 	report("lds", R_AX | R_BX,
128337f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
128437f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
128537f51a4aSWei Yongjun 
128637f51a4aSWei Yongjun 	MK_INSN(les, "push %es\n\t"
128737f51a4aSWei Yongjun 		     "les (%ebx), %eax\n\t"
128837f51a4aSWei Yongjun 		     "mov %es, %ebx\n\t"
128937f51a4aSWei Yongjun 		     "pop %es\n\t");
129037f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_les);
129137f51a4aSWei Yongjun 	report("les", R_AX | R_BX,
129237f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
129337f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
129437f51a4aSWei Yongjun 
129537f51a4aSWei Yongjun 	MK_INSN(lfs, "push %fs\n\t"
129637f51a4aSWei Yongjun 		     "lfs (%ebx), %eax\n\t"
129737f51a4aSWei Yongjun 		     "mov %fs, %ebx\n\t"
129837f51a4aSWei Yongjun 		     "pop %fs\n\t");
129937f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_lfs);
130037f51a4aSWei Yongjun 	report("lfs", R_AX | R_BX,
130137f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
130237f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
130337f51a4aSWei Yongjun 
130437f51a4aSWei Yongjun 	MK_INSN(lgs, "push %gs\n\t"
130537f51a4aSWei Yongjun 		     "lgs (%ebx), %eax\n\t"
130637f51a4aSWei Yongjun 		     "mov %gs, %ebx\n\t"
130737f51a4aSWei Yongjun 		     "pop %gs\n\t");
130837f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_lgs);
130937f51a4aSWei Yongjun 	report("lgs", R_AX | R_BX,
131037f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
131137f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
131237f51a4aSWei Yongjun 
131337f51a4aSWei Yongjun 	MK_INSN(lss, "push %ss\n\t"
131437f51a4aSWei Yongjun 		     "lss (%ebx), %eax\n\t"
131537f51a4aSWei Yongjun 		     "mov %ss, %ebx\n\t"
131637f51a4aSWei Yongjun 		     "pop %ss\n\t");
131737f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_lss);
131837f51a4aSWei Yongjun 	report("lss", R_AX | R_BX,
131937f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
132037f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
132137f51a4aSWei Yongjun }
132237f51a4aSWei Yongjun 
1323b1c7c575SWei Yongjun void test_jcxz(void)
1324b1c7c575SWei Yongjun {
1325b1c7c575SWei Yongjun 	MK_INSN(jcxz1, "jcxz 1f\n\t"
1326b1c7c575SWei Yongjun 		       "mov $0x1234, %eax\n\t"
1327b1c7c575SWei Yongjun 		       "1:\n\t");
1328b1c7c575SWei Yongjun 	MK_INSN(jcxz2, "mov $0x100, %ecx\n\t"
1329b1c7c575SWei Yongjun 		       "jcxz 1f\n\t"
1330b1c7c575SWei Yongjun 		       "mov $0x1234, %eax\n\t"
1331b1c7c575SWei Yongjun 		       "mov $0, %ecx\n\t"
1332b1c7c575SWei Yongjun 		       "1:\n\t");
1333b1c7c575SWei Yongjun 	MK_INSN(jcxz3, "mov $0x10000, %ecx\n\t"
1334b1c7c575SWei Yongjun 		       "jcxz 1f\n\t"
1335b1c7c575SWei Yongjun 		       "mov $0x1234, %eax\n\t"
1336b1c7c575SWei Yongjun 		       "1:\n\t");
1337b1c7c575SWei Yongjun 	MK_INSN(jecxz1, "jecxz 1f\n\t"
1338b1c7c575SWei Yongjun 			"mov $0x1234, %eax\n\t"
1339b1c7c575SWei Yongjun 			"1:\n\t");
1340b1c7c575SWei Yongjun 	MK_INSN(jecxz2, "mov $0x10000, %ecx\n\t"
1341b1c7c575SWei Yongjun 			"jecxz 1f\n\t"
1342b1c7c575SWei Yongjun 			"mov $0x1234, %eax\n\t"
1343b1c7c575SWei Yongjun 			"mov $0, %ecx\n\t"
1344b1c7c575SWei Yongjun 			"1:\n\t");
1345b1c7c575SWei Yongjun 
1346b1c7c575SWei Yongjun 	inregs = (struct regs){ 0 };
1347b1c7c575SWei Yongjun 
1348b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jcxz1);
1349b1c7c575SWei Yongjun 	report("jcxz short 1", 0, 1);
1350b1c7c575SWei Yongjun 
1351b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jcxz2);
1352b1c7c575SWei Yongjun 	report("jcxz short 2", R_AX, outregs.eax == 0x1234);
1353b1c7c575SWei Yongjun 
1354b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jcxz3);
1355b1c7c575SWei Yongjun 	report("jcxz short 3", R_CX, outregs.ecx == 0x10000);
1356b1c7c575SWei Yongjun 
1357b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jecxz1);
1358b1c7c575SWei Yongjun 	report("jecxz short 1", 0, 1);
1359b1c7c575SWei Yongjun 
1360b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jecxz2);
1361b1c7c575SWei Yongjun 	report("jecxz short 2", R_AX, outregs.eax == 0x1234);
1362b1c7c575SWei Yongjun }
1363b1c7c575SWei Yongjun 
13648f578e98SAvi Kivity static void test_cpuid(void)
13658f578e98SAvi Kivity {
13668f578e98SAvi Kivity     MK_INSN(cpuid, "cpuid");
13678f578e98SAvi Kivity     unsigned function = 0x1234;
13688f578e98SAvi Kivity     unsigned eax, ebx, ecx, edx;
13698f578e98SAvi Kivity 
13708f578e98SAvi Kivity     inregs.eax = eax = function;
13718f578e98SAvi Kivity     asm("cpuid" : "+a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx));
13728f578e98SAvi Kivity     exec_in_big_real_mode(&insn_cpuid);
13738f578e98SAvi Kivity     report("cpuid", R_AX|R_BX|R_CX|R_DX,
13748f578e98SAvi Kivity 	   outregs.eax == eax && outregs.ebx == ebx
13758f578e98SAvi Kivity 	   && outregs.ecx == ecx && outregs.edx == edx);
13768f578e98SAvi Kivity }
13778f578e98SAvi Kivity 
1378ed93f43bSAvi Kivity static void test_ss_base_for_esp_ebp(void)
1379ed93f43bSAvi Kivity {
1380ed93f43bSAvi Kivity     MK_INSN(ssrel1, "mov %ss, %ax; mov %bx, %ss; movl (%ebp), %ebx; mov %ax, %ss");
1381ed93f43bSAvi Kivity     MK_INSN(ssrel2, "mov %ss, %ax; mov %bx, %ss; movl (%ebp,%edi,8), %ebx; mov %ax, %ss");
1382ed93f43bSAvi Kivity     static unsigned array[] = { 0x12345678, 0, 0, 0, 0x87654321 };
1383ed93f43bSAvi Kivity 
1384ed93f43bSAvi Kivity     inregs.ebx = 1;
1385ed93f43bSAvi Kivity     inregs.ebp = (unsigned)array;
1386ed93f43bSAvi Kivity     exec_in_big_real_mode(&insn_ssrel1);
1387ed93f43bSAvi Kivity     report("ss relative addressing (1)", R_AX | R_BX, outregs.ebx == 0x87654321);
1388ed93f43bSAvi Kivity     inregs.ebx = 1;
1389ed93f43bSAvi Kivity     inregs.ebp = (unsigned)array;
1390ed93f43bSAvi Kivity     inregs.edi = 0;
1391ed93f43bSAvi Kivity     exec_in_big_real_mode(&insn_ssrel2);
1392ed93f43bSAvi Kivity     report("ss relative addressing (2)", R_AX | R_BX, outregs.ebx == 0x87654321);
1393ed93f43bSAvi Kivity }
1394ed93f43bSAvi Kivity 
1395c2281fa4SAvi Kivity static void test_sgdt_sidt(void)
1396c2281fa4SAvi Kivity {
1397c2281fa4SAvi Kivity     MK_INSN(sgdt, "sgdtw (%eax)");
1398c2281fa4SAvi Kivity     MK_INSN(sidt, "sidtw (%eax)");
1399c2281fa4SAvi Kivity     unsigned x, y;
1400c2281fa4SAvi Kivity 
1401c2281fa4SAvi Kivity     inregs.eax = (unsigned)&y;
1402c2281fa4SAvi Kivity     asm volatile("sgdtw %0" : "=m"(x));
1403c2281fa4SAvi Kivity     exec_in_big_real_mode(&insn_sgdt);
1404c2281fa4SAvi Kivity     report("sgdt", 0, x == y);
1405c2281fa4SAvi Kivity 
1406c2281fa4SAvi Kivity     inregs.eax = (unsigned)&y;
1407c2281fa4SAvi Kivity     asm volatile("sidtw %0" : "=m"(x));
1408c2281fa4SAvi Kivity     exec_in_big_real_mode(&insn_sidt);
1409c2281fa4SAvi Kivity     report("sidt", 0, x == y);
1410c2281fa4SAvi Kivity }
1411c2281fa4SAvi Kivity 
14127ae3645aSAvi Kivity static void test_lahf(void)
14137ae3645aSAvi Kivity {
14147ae3645aSAvi Kivity     MK_INSN(lahf, "pushfw; mov %al, (%esp); popfw; lahf");
14157ae3645aSAvi Kivity 
14167ae3645aSAvi Kivity     inregs.eax = 0xc7;
14177ae3645aSAvi Kivity     exec_in_big_real_mode(&insn_lahf);
14187ae3645aSAvi Kivity     report("lahf", R_AX, (outregs.eax >> 8) == inregs.eax);
14197ae3645aSAvi Kivity }
14207ae3645aSAvi Kivity 
1421fd9ea640SAvi Kivity static void test_movzx_movsx(void)
1422fd9ea640SAvi Kivity {
1423fd9ea640SAvi Kivity     MK_INSN(movsx, "movsx %al, %ebx");
1424fd9ea640SAvi Kivity     MK_INSN(movzx, "movzx %al, %ebx");
14253013e079SGleb Natapov     MK_INSN(movzsah, "movsx %ah, %ebx");
14263013e079SGleb Natapov     MK_INSN(movzxah, "movzx %ah, %ebx");
1427fd9ea640SAvi Kivity 
1428fd9ea640SAvi Kivity     inregs.eax = 0x1234569c;
14293013e079SGleb Natapov     inregs.esp = 0xffff;
1430fd9ea640SAvi Kivity     exec_in_big_real_mode(&insn_movsx);
1431fd9ea640SAvi Kivity     report("movsx", R_BX, outregs.ebx == (signed char)inregs.eax);
1432fd9ea640SAvi Kivity     exec_in_big_real_mode(&insn_movzx);
1433fd9ea640SAvi Kivity     report("movzx", R_BX, outregs.ebx == (unsigned char)inregs.eax);
14343013e079SGleb Natapov     exec_in_big_real_mode(&insn_movzsah);
14353013e079SGleb Natapov     report("movsx ah", R_BX, outregs.ebx == (signed char)(inregs.eax>>8));
14363013e079SGleb Natapov     exec_in_big_real_mode(&insn_movzxah);
14373013e079SGleb Natapov     report("movzx ah", R_BX, outregs.ebx == (unsigned char)(inregs.eax >> 8));
1438fd9ea640SAvi Kivity }
1439fd9ea640SAvi Kivity 
1440b493b2e8SAvi Kivity static void test_bswap(void)
1441b493b2e8SAvi Kivity {
1442b493b2e8SAvi Kivity     MK_INSN(bswap, "bswap %ecx");
1443b493b2e8SAvi Kivity 
1444b493b2e8SAvi Kivity     inregs.ecx = 0x12345678;
1445b493b2e8SAvi Kivity     exec_in_big_real_mode(&insn_bswap);
1446b493b2e8SAvi Kivity     report("bswap", R_CX, outregs.ecx == 0x78563412);
1447b493b2e8SAvi Kivity }
1448b493b2e8SAvi Kivity 
14498cd86387SGleb Natapov static void test_aad(void)
14508cd86387SGleb Natapov {
14518cd86387SGleb Natapov     MK_INSN(aad, "aad");
14528cd86387SGleb Natapov 
14538cd86387SGleb Natapov     inregs.eax = 0x12345678;
14548cd86387SGleb Natapov     exec_in_big_real_mode(&insn_aad);
14558cd86387SGleb Natapov     report("aad", R_AX, outregs.eax == 0x123400d4);
14568cd86387SGleb Natapov }
14578cd86387SGleb Natapov 
14582a9b5718SPaolo Bonzini static void test_aam(void)
14592a9b5718SPaolo Bonzini {
14602a9b5718SPaolo Bonzini     MK_INSN(aam, "aam");
14612a9b5718SPaolo Bonzini 
14622a9b5718SPaolo Bonzini     inregs.eax = 0x76543210;
14632a9b5718SPaolo Bonzini     exec_in_big_real_mode(&insn_aam);
14642a9b5718SPaolo Bonzini     report("aam", R_AX, outregs.eax == 0x76540106);
14652a9b5718SPaolo Bonzini }
14662a9b5718SPaolo Bonzini 
14672a9b5718SPaolo Bonzini static void test_xlat(void)
14682a9b5718SPaolo Bonzini {
14692a9b5718SPaolo Bonzini     MK_INSN(xlat, "xlat");
14702a9b5718SPaolo Bonzini     u8 table[256];
14712a9b5718SPaolo Bonzini     int i;
14722a9b5718SPaolo Bonzini 
14732a9b5718SPaolo Bonzini     for (i = 0; i < 256; i++) {
14742a9b5718SPaolo Bonzini         table[i] = i + 1;
14752a9b5718SPaolo Bonzini     }
14762a9b5718SPaolo Bonzini 
14772a9b5718SPaolo Bonzini     inregs.eax = 0x89abcdef;
14782a9b5718SPaolo Bonzini     inregs.ebx = (u32)table;
14792a9b5718SPaolo Bonzini     exec_in_big_real_mode(&insn_xlat);
14802a9b5718SPaolo Bonzini     report("xlat", R_AX, outregs.eax == 0x89abcdf0);
14812a9b5718SPaolo Bonzini }
14822a9b5718SPaolo Bonzini 
14832a9b5718SPaolo Bonzini static void test_salc(void)
14842a9b5718SPaolo Bonzini {
14852a9b5718SPaolo Bonzini     MK_INSN(clc_salc, "clc; .byte 0xd6");
14862a9b5718SPaolo Bonzini     MK_INSN(stc_salc, "stc; .byte 0xd6");
14872a9b5718SPaolo Bonzini 
14882a9b5718SPaolo Bonzini     inregs.eax = 0x12345678;
14892a9b5718SPaolo Bonzini     exec_in_big_real_mode(&insn_clc_salc);
14902a9b5718SPaolo Bonzini     report("salc (1)", R_AX, outregs.eax == 0x12345600);
14912a9b5718SPaolo Bonzini     exec_in_big_real_mode(&insn_stc_salc);
14922a9b5718SPaolo Bonzini     report("salc (2)", R_AX, outregs.eax == 0x123456ff);
14932a9b5718SPaolo Bonzini }
14942a9b5718SPaolo Bonzini 
14950987db7aSGleb Natapov static void test_fninit(void)
14960987db7aSGleb Natapov {
14970987db7aSGleb Natapov 	u16 fcw = -1, fsw = -1;
14980987db7aSGleb Natapov 	MK_INSN(fninit, "fninit ; fnstsw (%eax) ; fnstcw (%ebx)");
14990987db7aSGleb Natapov 
15000987db7aSGleb Natapov 	inregs.eax = (u32)&fsw;
15010987db7aSGleb Natapov 	inregs.ebx = (u32)&fcw;
15020987db7aSGleb Natapov 
15030987db7aSGleb Natapov 	exec_in_big_real_mode(&insn_fninit);
15040987db7aSGleb Natapov 	report("fninit", 0, fsw == 0 && (fcw & 0x103f) == 0x003f);
15050987db7aSGleb Natapov }
15060987db7aSGleb Natapov 
1507*1a4c03a0SArthur Chunqi Li static void test_nopl(void)
1508*1a4c03a0SArthur Chunqi Li {
1509*1a4c03a0SArthur Chunqi Li 	MK_INSN(nopl1, ".byte 0x90\n\r"); // 1 byte nop
1510*1a4c03a0SArthur Chunqi Li 	MK_INSN(nopl2, ".byte 0x66, 0x90\n\r"); // 2 bytes nop
1511*1a4c03a0SArthur Chunqi Li 	MK_INSN(nopl3, ".byte 0x0f, 0x1f, 0x00\n\r"); // 3 bytes nop
1512*1a4c03a0SArthur Chunqi Li 	MK_INSN(nopl4, ".byte 0x0f, 0x1f, 0x40, 0x00\n\r"); // 4 bytes nop
1513*1a4c03a0SArthur Chunqi Li 	exec_in_big_real_mode(&insn_nopl1);
1514*1a4c03a0SArthur Chunqi Li 	exec_in_big_real_mode(&insn_nopl2);
1515*1a4c03a0SArthur Chunqi Li 	exec_in_big_real_mode(&insn_nopl3);
1516*1a4c03a0SArthur Chunqi Li 	exec_in_big_real_mode(&insn_nopl4);
1517*1a4c03a0SArthur Chunqi Li 	report("nopl", 0, 1);
1518*1a4c03a0SArthur Chunqi Li }
1519*1a4c03a0SArthur Chunqi Li 
15207d36db35SAvi Kivity void realmode_start(void)
15217d36db35SAvi Kivity {
15227d36db35SAvi Kivity 	test_null();
15237d36db35SAvi Kivity 
15247d36db35SAvi Kivity 	test_shld();
15257d36db35SAvi Kivity 	test_push_pop();
15267d36db35SAvi Kivity 	test_pusha_popa();
15277d36db35SAvi Kivity 	test_mov_imm();
15287d36db35SAvi Kivity 	test_cmp_imm();
15297d36db35SAvi Kivity 	test_add_imm();
15307d36db35SAvi Kivity 	test_sub_imm();
15317d36db35SAvi Kivity 	test_xor_imm();
15327d36db35SAvi Kivity 	test_io();
15337d36db35SAvi Kivity 	test_eflags_insn();
15347d36db35SAvi Kivity 	test_jcc_short();
15357d36db35SAvi Kivity 	test_jcc_near();
15367d36db35SAvi Kivity 	/* test_call() uses short jump so call it after testing jcc */
15377d36db35SAvi Kivity 	test_call();
15387d36db35SAvi Kivity 	/* long jmp test uses call near so test it after testing call */
15397d36db35SAvi Kivity 	test_long_jmp();
15407d36db35SAvi Kivity 	test_xchg();
15417d36db35SAvi Kivity 	test_iret();
154296b9ca1eSMohammed Gamal 	test_int();
1543fa74f8a6SMohammed Gamal 	test_imul();
154459317bd1SMohammed Gamal 	test_mul();
15450d4c7614SMohammed Gamal 	test_div();
15460d4c7614SMohammed Gamal 	test_idiv();
1547eacef4e2SWei Yongjun 	test_loopcc();
15486e293cf5SWei Yongjun 	test_cbw();
15490cbd5b06SMohammed Gamal 	test_cwd_cdq();
1550b274feedSAvi Kivity 	test_das();
155137f51a4aSWei Yongjun 	test_lds_lss();
1552b1c7c575SWei Yongjun 	test_jcxz();
15538f578e98SAvi Kivity 	test_cpuid();
1554ed93f43bSAvi Kivity 	test_ss_base_for_esp_ebp();
1555c2281fa4SAvi Kivity 	test_sgdt_sidt();
15567ae3645aSAvi Kivity 	test_lahf();
1557fd9ea640SAvi Kivity 	test_movzx_movsx();
1558b493b2e8SAvi Kivity 	test_bswap();
15598cd86387SGleb Natapov 	test_aad();
15602a9b5718SPaolo Bonzini 	test_aam();
15612a9b5718SPaolo Bonzini 	test_xlat();
15622a9b5718SPaolo Bonzini 	test_salc();
15630987db7aSGleb Natapov 	test_fninit();
1564*1a4c03a0SArthur Chunqi Li 	test_nopl();
15657d36db35SAvi Kivity 
15667d36db35SAvi Kivity 	exit(0);
15677d36db35SAvi Kivity }
15687d36db35SAvi Kivity 
15697d36db35SAvi Kivity unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff };
15707d36db35SAvi Kivity 
15717d36db35SAvi Kivity struct __attribute__((packed)) {
15727d36db35SAvi Kivity 	unsigned short limit;
15737d36db35SAvi Kivity 	void *base;
15747d36db35SAvi Kivity } r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt };
15757d36db35SAvi Kivity 
15767d36db35SAvi Kivity asm(
15777d36db35SAvi Kivity 	".section .init \n\t"
15787d36db35SAvi Kivity 
15797d36db35SAvi Kivity 	".code32 \n\t"
15807d36db35SAvi Kivity 
15817d36db35SAvi Kivity 	"mb_magic = 0x1BADB002 \n\t"
15827d36db35SAvi Kivity 	"mb_flags = 0x0 \n\t"
15837d36db35SAvi Kivity 
15847d36db35SAvi Kivity 	"# multiboot header \n\t"
15857d36db35SAvi Kivity 	".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t"
15867d36db35SAvi Kivity 
15877d36db35SAvi Kivity 	".globl start \n\t"
15887d36db35SAvi Kivity 	".data \n\t"
15897d36db35SAvi Kivity 	". = . + 4096 \n\t"
15907d36db35SAvi Kivity 	"stacktop: \n\t"
15917d36db35SAvi Kivity 
15927d36db35SAvi Kivity 	".text \n\t"
15937d36db35SAvi Kivity 	"start: \n\t"
15947d36db35SAvi Kivity 	"lgdt r_gdt_descr \n\t"
15957d36db35SAvi Kivity 	"ljmp $8, $1f; 1: \n\t"
15967d36db35SAvi Kivity 	".code16gcc \n\t"
15977d36db35SAvi Kivity 	"mov $16, %eax \n\t"
15987d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
15997d36db35SAvi Kivity 	"mov %ax, %es \n\t"
16007d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
16017d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
16027d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
16037d36db35SAvi Kivity 	"mov %cr0, %eax \n\t"
16047d36db35SAvi Kivity 	"btc $0, %eax \n\t"
16057d36db35SAvi Kivity 	"mov %eax, %cr0 \n\t"
16067d36db35SAvi Kivity 	"ljmp $0, $realmode_entry \n\t"
16077d36db35SAvi Kivity 
16087d36db35SAvi Kivity 	"realmode_entry: \n\t"
16097d36db35SAvi Kivity 
16107d36db35SAvi Kivity 	"xor %ax, %ax \n\t"
16117d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
16127d36db35SAvi Kivity 	"mov %ax, %es \n\t"
16137d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
16147d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
16157d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
16167d36db35SAvi Kivity 	"mov $stacktop, %esp\n\t"
16177d36db35SAvi Kivity 	"ljmp $0, $realmode_start \n\t"
16187d36db35SAvi Kivity 
16197d36db35SAvi Kivity 	".code16gcc \n\t"
16207d36db35SAvi Kivity 	);
1621