xref: /kvm-unit-tests/x86/realmode.c (revision 18ba9083541d27a86f68a649f9d7ce75b2a32c09)
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 
4844f66bc86SBruce Rogers asm ("retf_imm: lretw $10");
4854f66bc86SBruce Rogers extern void retf_imm();
4864f66bc86SBruce Rogers 
4877d36db35SAvi Kivity void test_call(void)
4887d36db35SAvi Kivity {
4897d36db35SAvi Kivity 	u32 esp[16];
490c0b7268dSAvi Kivity 	u32 addr;
4917d36db35SAvi Kivity 
49218253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
4937d36db35SAvi Kivity 	inregs.esp = (u32)esp;
4947d36db35SAvi Kivity 
4957d36db35SAvi Kivity 	MK_INSN(call1, "mov $test_function, %eax \n\t"
4967d36db35SAvi Kivity 		       "call *%eax\n\t");
4977d36db35SAvi Kivity 	MK_INSN(call_near1, "jmp 2f\n\t"
4987d36db35SAvi Kivity 			    "1: mov $0x1234, %eax\n\t"
4997d36db35SAvi Kivity 			    "ret\n\t"
5007d36db35SAvi Kivity 			    "2: call 1b\t");
5017d36db35SAvi Kivity 	MK_INSN(call_near2, "call 1f\n\t"
5027d36db35SAvi Kivity 			    "jmp 2f\n\t"
5037d36db35SAvi Kivity 			    "1: mov $0x1234, %eax\n\t"
5047d36db35SAvi Kivity 			    "ret\n\t"
5057d36db35SAvi Kivity 			    "2:\t");
506c0b7268dSAvi Kivity 	MK_INSN(call_far1,  "lcallw *(%ebx)\n\t");
507556d2680SWei Yongjun 	MK_INSN(call_far2,  "lcallw $0, $retf\n\t");
508c6061817SAvi Kivity 	MK_INSN(ret_imm,    "sub $10, %sp; jmp 2f; 1: retw $10; 2: callw 1b");
5094f66bc86SBruce Rogers 	MK_INSN(retf_imm,   "sub $10, %sp; lcallw $0, $retf_imm");
5107d36db35SAvi Kivity 
51118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_call1);
5126055ea1fSAvi Kivity 	report("call 1", R_AX, outregs.eax == 0x1234);
5137d36db35SAvi Kivity 
51418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_call_near1);
5156055ea1fSAvi Kivity 	report("call near 1", R_AX, outregs.eax == 0x1234);
5167d36db35SAvi Kivity 
51718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_call_near2);
5186055ea1fSAvi Kivity 	report("call near 2", R_AX, outregs.eax == 0x1234);
519c0b7268dSAvi Kivity 
520c0b7268dSAvi Kivity 	addr = (((unsigned)retf >> 4) << 16) | ((unsigned)retf & 0x0f);
521c0b7268dSAvi Kivity 	inregs.ebx = (unsigned)&addr;
52218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_call_far1);
5236055ea1fSAvi Kivity 	report("call far 1", 0, 1);
524c6061817SAvi Kivity 
525556d2680SWei Yongjun 	exec_in_big_real_mode(&insn_call_far2);
526556d2680SWei Yongjun 	report("call far 2", 0, 1);
527556d2680SWei Yongjun 
52818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_ret_imm);
5296055ea1fSAvi Kivity 	report("ret imm 1", 0, 1);
5304f66bc86SBruce Rogers 
5314f66bc86SBruce Rogers 	exec_in_big_real_mode(&insn_retf_imm);
5324f66bc86SBruce Rogers 	report("retf imm 1", 0, 1);
5337d36db35SAvi Kivity }
5347d36db35SAvi Kivity 
5357d36db35SAvi Kivity void test_jcc_short(void)
5367d36db35SAvi Kivity {
5377d36db35SAvi Kivity 	MK_INSN(jnz_short1, "jnz 1f\n\t"
5387d36db35SAvi Kivity 			    "mov $0x1234, %eax\n\t"
5397d36db35SAvi Kivity 		            "1:\n\t");
5407d36db35SAvi Kivity 	MK_INSN(jnz_short2, "1:\n\t"
5417d36db35SAvi Kivity 			    "cmp $0x1234, %eax\n\t"
5427d36db35SAvi Kivity 			    "mov $0x1234, %eax\n\t"
5437d36db35SAvi Kivity 		            "jnz 1b\n\t");
5447d36db35SAvi Kivity 	MK_INSN(jmp_short1, "jmp 1f\n\t"
5457d36db35SAvi Kivity 		      "mov $0x1234, %eax\n\t"
5467d36db35SAvi Kivity 		      "1:\n\t");
5477d36db35SAvi Kivity 
54818253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
5497d36db35SAvi Kivity 
55018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jnz_short1);
5516055ea1fSAvi Kivity 	report("jnz short 1", ~0, 1);
55218253fdeSAvi Kivity 
55318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jnz_short2);
5546055ea1fSAvi Kivity 	report("jnz short 2", R_AX, (outregs.eflags & (1 << 6)));
5557d36db35SAvi Kivity 
55618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jmp_short1);
5576055ea1fSAvi Kivity 	report("jmp short 1", ~0, 1);
5587d36db35SAvi Kivity }
5597d36db35SAvi Kivity 
5607d36db35SAvi Kivity void test_jcc_near(void)
5617d36db35SAvi Kivity {
5627d36db35SAvi Kivity 	/* encode near jmp manually. gas will not do it if offsets < 127 byte */
5637d36db35SAvi Kivity 	MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t"
5647d36db35SAvi Kivity 		           "mov $0x1234, %eax\n\t");
5657d36db35SAvi Kivity 	MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t"
5667d36db35SAvi Kivity 			   "mov $0x1234, %eax\n\t"
5677d36db35SAvi Kivity 		           ".byte 0x0f, 0x85, 0xf0, 0xff\n\t");
5687d36db35SAvi Kivity 	MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t"
5697d36db35SAvi Kivity 		           "mov $0x1234, %eax\n\t");
5707d36db35SAvi Kivity 
57118253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
5727d36db35SAvi Kivity 
57318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jnz_near1);
5746055ea1fSAvi Kivity 	report("jnz near 1", 0, 1);
57518253fdeSAvi Kivity 
57618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jnz_near2);
5776055ea1fSAvi Kivity 	report("jnz near 2", R_AX, outregs.eflags & (1 << 6));
5787d36db35SAvi Kivity 
57918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_jmp_near1);
5806055ea1fSAvi Kivity 	report("jmp near 1", 0, 1);
5817d36db35SAvi Kivity }
5827d36db35SAvi Kivity 
5837d36db35SAvi Kivity void test_long_jmp()
5847d36db35SAvi Kivity {
5857d36db35SAvi Kivity 	u32 esp[16];
5867d36db35SAvi Kivity 
58718253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
5884aa22949SAvi Kivity 	inregs.esp = (u32)(esp+16);
5897d36db35SAvi Kivity 	MK_INSN(long_jmp, "call 1f\n\t"
5907d36db35SAvi Kivity 			  "jmp 2f\n\t"
5917d36db35SAvi Kivity 			  "1: jmp $0, $test_function\n\t"
5927d36db35SAvi Kivity 		          "2:\n\t");
59318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_long_jmp);
5946055ea1fSAvi Kivity 	report("jmp far 1", R_AX, outregs.eax == 0x1234);
5957d36db35SAvi Kivity }
596fa74f8a6SMohammed Gamal 
5977d36db35SAvi Kivity void test_push_pop()
5987d36db35SAvi Kivity {
5997d36db35SAvi Kivity 	MK_INSN(push32, "mov $0x12345678, %eax\n\t"
6007d36db35SAvi Kivity 			"push %eax\n\t"
6017d36db35SAvi Kivity 			"pop %ebx\n\t");
6027d36db35SAvi Kivity 	MK_INSN(push16, "mov $0x1234, %ax\n\t"
6037d36db35SAvi Kivity 			"push %ax\n\t"
6047d36db35SAvi Kivity 			"pop %bx\n\t");
6057d36db35SAvi Kivity 
6067d36db35SAvi Kivity 	MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten
6077d36db35SAvi Kivity 			 "mov $0x123, %ax\n\t"
6087d36db35SAvi Kivity 			 "mov %ax, %es\n\t"
6097d36db35SAvi Kivity 			 "push %es\n\t"
6107d36db35SAvi Kivity 			 "pop %bx \n\t"
6117d36db35SAvi Kivity 			 );
6127d36db35SAvi Kivity 	MK_INSN(pop_es, "push %ax\n\t"
6137d36db35SAvi Kivity 			"pop %es\n\t"
6147d36db35SAvi Kivity 			"mov %es, %bx\n\t"
6157d36db35SAvi Kivity 			);
6167d36db35SAvi Kivity 	MK_INSN(push_pop_ss, "push %ss\n\t"
6177d36db35SAvi Kivity 			     "pushw %ax\n\t"
6187d36db35SAvi Kivity 			     "popw %ss\n\t"
6197d36db35SAvi Kivity 			     "mov %ss, %bx\n\t"
6207d36db35SAvi Kivity 			     "pop %ss\n\t"
6217d36db35SAvi Kivity 			);
6227d36db35SAvi Kivity 	MK_INSN(push_pop_fs, "push %fs\n\t"
6237d36db35SAvi Kivity 			     "pushl %eax\n\t"
6247d36db35SAvi Kivity 			     "popl %fs\n\t"
6257d36db35SAvi Kivity 			     "mov %fs, %ebx\n\t"
6267d36db35SAvi Kivity 			     "pop %fs\n\t"
6277d36db35SAvi Kivity 			);
62809b657b6SAvi Kivity 	MK_INSN(push_pop_high_esp_bits,
62909b657b6SAvi Kivity 		"xor $0x12340000, %esp \n\t"
63009b657b6SAvi Kivity 		"push %ax; \n\t"
63109b657b6SAvi Kivity 		"xor $0x12340000, %esp \n\t"
63209b657b6SAvi Kivity 		"pop %bx");
6337d36db35SAvi Kivity 
63418253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
63518253fdeSAvi Kivity 
63618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push32);
6376055ea1fSAvi Kivity 	report("push/pop 1", R_AX|R_BX,
6386055ea1fSAvi Kivity 	       outregs.eax == outregs.ebx && outregs.eax == 0x12345678);
6397d36db35SAvi Kivity 
64018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push16);
6416055ea1fSAvi Kivity 	report("push/pop 2", R_AX|R_BX,
6426055ea1fSAvi Kivity 	       outregs.eax == outregs.ebx && outregs.eax == 0x1234);
6437d36db35SAvi Kivity 
64418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push_es);
6456055ea1fSAvi Kivity 	report("push/pop 3", R_AX|R_BX,
6466055ea1fSAvi Kivity 	       outregs.ebx == outregs.eax && outregs.eax == 0x123);
6477d36db35SAvi Kivity 
64818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_pop_es);
6496055ea1fSAvi Kivity 	report("push/pop 4", R_AX|R_BX, outregs.ebx == outregs.eax);
6507d36db35SAvi Kivity 
65118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push_pop_ss);
6526055ea1fSAvi Kivity 	report("push/pop 5", R_AX|R_BX, outregs.ebx == outregs.eax);
6537d36db35SAvi Kivity 
65418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_push_pop_fs);
6556055ea1fSAvi Kivity 	report("push/pop 6", R_AX|R_BX, outregs.ebx == outregs.eax);
65609b657b6SAvi Kivity 
65709b657b6SAvi Kivity 	inregs.eax = 0x9977;
65809b657b6SAvi Kivity 	inregs.ebx = 0x7799;
65909b657b6SAvi Kivity 	exec_in_big_real_mode(&insn_push_pop_high_esp_bits);
66009b657b6SAvi Kivity 	report("push/pop with high bits set in %esp", R_BX, outregs.ebx == 0x9977);
6617d36db35SAvi Kivity }
6627d36db35SAvi Kivity 
6637d36db35SAvi Kivity void test_null(void)
6647d36db35SAvi Kivity {
665d4dc402cSAvi Kivity 	MK_INSN(null, "");
666d4dc402cSAvi Kivity 
66718253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
66818253fdeSAvi Kivity 
66918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_null);
6706055ea1fSAvi Kivity 	report("null", 0, 1);
6717d36db35SAvi Kivity }
6727d36db35SAvi Kivity 
6737d36db35SAvi Kivity struct {
6747d36db35SAvi Kivity     char stack[500];
6757d36db35SAvi Kivity     char top[];
6767d36db35SAvi Kivity } tmp_stack;
6777d36db35SAvi Kivity 
6787d36db35SAvi Kivity void test_pusha_popa()
6797d36db35SAvi Kivity {
6807d36db35SAvi Kivity 	MK_INSN(pusha, "pusha\n\t"
6817d36db35SAvi Kivity 		       "pop %edi\n\t"
6827d36db35SAvi Kivity 		       "pop %esi\n\t"
6837d36db35SAvi Kivity 		       "pop %ebp\n\t"
6847d36db35SAvi Kivity 		       "add $4, %esp\n\t"
6857d36db35SAvi Kivity 		       "pop %ebx\n\t"
6867d36db35SAvi Kivity 		       "pop %edx\n\t"
6877d36db35SAvi Kivity 		       "pop %ecx\n\t"
6887d36db35SAvi Kivity 		       "pop %eax\n\t"
6897d36db35SAvi Kivity 		       );
6907d36db35SAvi Kivity 
6917d36db35SAvi Kivity 	MK_INSN(popa, "push %eax\n\t"
6927d36db35SAvi Kivity 		      "push %ecx\n\t"
6937d36db35SAvi Kivity 		      "push %edx\n\t"
6947d36db35SAvi Kivity 		      "push %ebx\n\t"
6957d36db35SAvi Kivity 		      "push %esp\n\t"
6967d36db35SAvi Kivity 		      "push %ebp\n\t"
6977d36db35SAvi Kivity 		      "push %esi\n\t"
6987d36db35SAvi Kivity 		      "push %edi\n\t"
6997d36db35SAvi Kivity 		      "popa\n\t"
7007d36db35SAvi Kivity 		      );
7017d36db35SAvi Kivity 
70218253fdeSAvi Kivity 	inregs = (struct regs){ .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = (unsigned long)&tmp_stack.top };
7037d36db35SAvi Kivity 
70418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_pusha);
7056055ea1fSAvi Kivity 	report("pusha/popa 1", 0, 1);
70618253fdeSAvi Kivity 
70718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_popa);
7086055ea1fSAvi Kivity 	report("pusha/popa 1", 0, 1);
7097d36db35SAvi Kivity }
7107d36db35SAvi Kivity 
7117d36db35SAvi Kivity void test_iret()
7127d36db35SAvi Kivity {
7137d36db35SAvi Kivity 	MK_INSN(iret32, "pushf\n\t"
7147d36db35SAvi Kivity 			"pushl %cs\n\t"
7157d36db35SAvi Kivity 			"call 1f\n\t" /* a near call will push eip onto the stack */
7167d36db35SAvi Kivity 			"jmp 2f\n\t"
7177d36db35SAvi Kivity 			"1: iret\n\t"
7187d36db35SAvi Kivity 			"2:\n\t"
7197d36db35SAvi Kivity 		     );
7207d36db35SAvi Kivity 
7217d36db35SAvi Kivity 	MK_INSN(iret16, "pushfw\n\t"
7227d36db35SAvi Kivity 			"pushw %cs\n\t"
7237d36db35SAvi Kivity 			"callw 1f\n\t"
7247d36db35SAvi Kivity 			"jmp 2f\n\t"
7257d36db35SAvi Kivity 			"1: iretw\n\t"
7267d36db35SAvi Kivity 			"2:\n\t");
7277d36db35SAvi Kivity 
7287d36db35SAvi Kivity 	MK_INSN(iret_flags32, "pushfl\n\t"
7297d36db35SAvi Kivity 			      "popl %eax\n\t"
7307d36db35SAvi Kivity 			      "andl $~0x2, %eax\n\t"
7317d36db35SAvi Kivity 			      "orl $0xffc08028, %eax\n\t"
7327d36db35SAvi Kivity 			      "pushl %eax\n\t"
7337d36db35SAvi Kivity 			      "pushl %cs\n\t"
7347d36db35SAvi Kivity 			      "call 1f\n\t"
7357d36db35SAvi Kivity 			      "jmp 2f\n\t"
7367d36db35SAvi Kivity 			      "1: iret\n\t"
7377d36db35SAvi Kivity 			      "2:\n\t");
7387d36db35SAvi Kivity 
7397d36db35SAvi Kivity 	MK_INSN(iret_flags16, "pushfw\n\t"
7407d36db35SAvi Kivity 			      "popw %ax\n\t"
7417d36db35SAvi Kivity 			      "and $~0x2, %ax\n\t"
7427d36db35SAvi Kivity 			      "or $0x8028, %ax\n\t"
7437d36db35SAvi Kivity 			      "pushw %ax\n\t"
7447d36db35SAvi Kivity 			      "pushw %cs\n\t"
7457d36db35SAvi Kivity 			      "callw 1f\n\t"
7467d36db35SAvi Kivity 			      "jmp 2f\n\t"
7477d36db35SAvi Kivity 			      "1: iretw\n\t"
7487d36db35SAvi Kivity 			      "2:\n\t");
7497d36db35SAvi Kivity 
75018253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
7517d36db35SAvi Kivity 
75218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_iret32);
7536055ea1fSAvi Kivity 	report("iret 1", 0, 1);
7547d36db35SAvi Kivity 
75518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_iret16);
7566055ea1fSAvi Kivity 	report("iret 2", 0, 1);
7577d36db35SAvi Kivity 
75818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_iret_flags32);
7596055ea1fSAvi Kivity 	report("iret 3", R_AX, 1);
76018253fdeSAvi Kivity 
76118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_iret_flags16);
7626055ea1fSAvi Kivity 	report("iret 4", R_AX, 1);
7637d36db35SAvi Kivity }
7647d36db35SAvi Kivity 
76596b9ca1eSMohammed Gamal void test_int()
76696b9ca1eSMohammed Gamal {
76718253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
76896b9ca1eSMohammed Gamal 
76996b9ca1eSMohammed Gamal 	*(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */
77096b9ca1eSMohammed Gamal 	*(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */
77196b9ca1eSMohammed Gamal 
77296b9ca1eSMohammed Gamal 	MK_INSN(int11, "int $0x11\n\t");
77396b9ca1eSMohammed Gamal 
77418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_int11);
7756055ea1fSAvi Kivity 	report("int 1", 0, 1);
77696b9ca1eSMohammed Gamal }
77796b9ca1eSMohammed Gamal 
778fa74f8a6SMohammed Gamal void test_imul()
779fa74f8a6SMohammed Gamal {
780fa74f8a6SMohammed Gamal 	MK_INSN(imul8_1, "mov $2, %al\n\t"
781fa74f8a6SMohammed Gamal 			"mov $-4, %cx\n\t"
782fa74f8a6SMohammed Gamal 			"imul %cl\n\t");
783fa74f8a6SMohammed Gamal 
784fa74f8a6SMohammed Gamal 	MK_INSN(imul16_1, "mov $2, %ax\n\t"
785fa74f8a6SMohammed Gamal 		      "mov $-4, %cx\n\t"
786fa74f8a6SMohammed Gamal 		      "imul %cx\n\t");
787fa74f8a6SMohammed Gamal 
788fa74f8a6SMohammed Gamal 	MK_INSN(imul32_1, "mov $2, %eax\n\t"
789fa74f8a6SMohammed Gamal 		       "mov $-4, %ecx\n\t"
790fa74f8a6SMohammed Gamal 		       "imul %ecx\n\t");
791fa74f8a6SMohammed Gamal 
792fa74f8a6SMohammed Gamal 	MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t"
793fa74f8a6SMohammed Gamal 			"mov $4, %cx\n\t"
794fa74f8a6SMohammed Gamal 			"imul %cl\n\t");
795fa74f8a6SMohammed Gamal 
796fa74f8a6SMohammed Gamal 	MK_INSN(imul16_2, "mov $2, %ax\n\t"
797fa74f8a6SMohammed Gamal 			"mov $4, %cx\n\t"
798fa74f8a6SMohammed Gamal 			"imul %cx\n\t");
799fa74f8a6SMohammed Gamal 
800fa74f8a6SMohammed Gamal 	MK_INSN(imul32_2, "mov $2, %eax\n\t"
801fa74f8a6SMohammed Gamal 			"mov $4, %ecx\n\t"
802fa74f8a6SMohammed Gamal 			"imul %ecx\n\t");
803fa74f8a6SMohammed Gamal 
80418253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
80518253fdeSAvi Kivity 
80618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul8_1);
8076055ea1fSAvi Kivity 	report("imul 1", R_AX | R_CX | R_DX, (outregs.eax & 0xff) == (u8)-8);
808fa74f8a6SMohammed Gamal 
80918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul16_1);
8106055ea1fSAvi Kivity 	report("imul 2", R_AX | R_CX | R_DX, outregs.eax == (u16)-8);
811fa74f8a6SMohammed Gamal 
81218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul32_1);
8136055ea1fSAvi Kivity 	report("imul 3", R_AX | R_CX | R_DX, outregs.eax == (u32)-8);
814fa74f8a6SMohammed Gamal 
81518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul8_2);
8166055ea1fSAvi Kivity 	report("imul 4", R_AX | R_CX | R_DX,
8176055ea1fSAvi Kivity 	       (outregs.eax & 0xffff) == 8
81881050840SAvi Kivity 	       && (outregs.eax & 0xffff0000) == 0x12340000);
819fa74f8a6SMohammed Gamal 
82018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul16_2);
8216055ea1fSAvi Kivity 	report("imul 5", R_AX | R_CX | R_DX, outregs.eax == 8);
822fa74f8a6SMohammed Gamal 
82318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_imul32_2);
8246055ea1fSAvi Kivity 	report("imul 6", R_AX | R_CX | R_DX, outregs.eax == 8);
825fa74f8a6SMohammed Gamal }
826fa74f8a6SMohammed Gamal 
82759317bd1SMohammed Gamal void test_mul()
82859317bd1SMohammed Gamal {
82959317bd1SMohammed Gamal 	MK_INSN(mul8, "mov $2, %al\n\t"
83059317bd1SMohammed Gamal 			"mov $4, %cx\n\t"
83159317bd1SMohammed Gamal 			"imul %cl\n\t");
83259317bd1SMohammed Gamal 
83359317bd1SMohammed Gamal 	MK_INSN(mul16, "mov $2, %ax\n\t"
83459317bd1SMohammed Gamal 			"mov $4, %cx\n\t"
83559317bd1SMohammed Gamal 			"imul %cx\n\t");
83659317bd1SMohammed Gamal 
83759317bd1SMohammed Gamal 	MK_INSN(mul32, "mov $2, %eax\n\t"
83859317bd1SMohammed Gamal 			"mov $4, %ecx\n\t"
83959317bd1SMohammed Gamal 			"imul %ecx\n\t");
84059317bd1SMohammed Gamal 
84118253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
84218253fdeSAvi Kivity 
84318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mul8);
8446055ea1fSAvi Kivity 	report("mul 1", R_AX | R_CX | R_DX, (outregs.eax & 0xff) == 8);
84559317bd1SMohammed Gamal 
84618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mul16);
8476055ea1fSAvi Kivity 	report("mul 2", R_AX | R_CX | R_DX, outregs.eax == 8);
84859317bd1SMohammed Gamal 
84918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_mul32);
8506055ea1fSAvi Kivity 	report("mul 3", R_AX | R_CX | R_DX, outregs.eax == 8);
85159317bd1SMohammed Gamal }
85259317bd1SMohammed Gamal 
8530d4c7614SMohammed Gamal void test_div()
8540d4c7614SMohammed Gamal {
8550d4c7614SMohammed Gamal 	MK_INSN(div8, "mov $257, %ax\n\t"
8560d4c7614SMohammed Gamal 			"mov $2, %cl\n\t"
8570d4c7614SMohammed Gamal 			"div %cl\n\t");
8580d4c7614SMohammed Gamal 
8590d4c7614SMohammed Gamal 	MK_INSN(div16, "mov $512, %ax\n\t"
8600d4c7614SMohammed Gamal 			"mov $5, %cx\n\t"
8610d4c7614SMohammed Gamal 			"div %cx\n\t");
8620d4c7614SMohammed Gamal 
8630d4c7614SMohammed Gamal 	MK_INSN(div32, "mov $512, %eax\n\t"
8640d4c7614SMohammed Gamal 			"mov $5, %ecx\n\t"
8650d4c7614SMohammed Gamal 			"div %ecx\n\t");
8660d4c7614SMohammed Gamal 
86718253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
86818253fdeSAvi Kivity 
86918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_div8);
8706055ea1fSAvi Kivity 	report("div 1", R_AX | R_CX | R_DX, outregs.eax == 384);
8710d4c7614SMohammed Gamal 
87218253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_div16);
8736055ea1fSAvi Kivity 	report("div 2", R_AX | R_CX | R_DX,
8746055ea1fSAvi Kivity 	       outregs.eax == 102 && outregs.edx == 2);
8750d4c7614SMohammed Gamal 
87618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_div32);
8776055ea1fSAvi Kivity 	report("div 3", R_AX | R_CX | R_DX,
8786055ea1fSAvi Kivity 	       outregs.eax == 102 && outregs.edx == 2);
8790d4c7614SMohammed Gamal }
8800d4c7614SMohammed Gamal 
8810d4c7614SMohammed Gamal void test_idiv()
8820d4c7614SMohammed Gamal {
8830d4c7614SMohammed Gamal 	MK_INSN(idiv8, "mov $256, %ax\n\t"
8840d4c7614SMohammed Gamal 			"mov $-2, %cl\n\t"
8850d4c7614SMohammed Gamal 			"idiv %cl\n\t");
8860d4c7614SMohammed Gamal 
8870d4c7614SMohammed Gamal 	MK_INSN(idiv16, "mov $512, %ax\n\t"
8880d4c7614SMohammed Gamal 			"mov $-2, %cx\n\t"
8890d4c7614SMohammed Gamal 			"idiv %cx\n\t");
8900d4c7614SMohammed Gamal 
8910d4c7614SMohammed Gamal 	MK_INSN(idiv32, "mov $512, %eax\n\t"
8920d4c7614SMohammed Gamal 			"mov $-2, %ecx\n\t"
8930d4c7614SMohammed Gamal 			"idiv %ecx\n\t");
8940d4c7614SMohammed Gamal 
89518253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
89618253fdeSAvi Kivity 
89718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_idiv8);
8986055ea1fSAvi Kivity 	report("idiv 1", R_AX | R_CX | R_DX, outregs.eax == (u8)-128);
8990d4c7614SMohammed Gamal 
90018253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_idiv16);
9016055ea1fSAvi Kivity 	report("idiv 2", R_AX | R_CX | R_DX, outregs.eax == (u16)-256);
9020d4c7614SMohammed Gamal 
90318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_idiv32);
9046055ea1fSAvi Kivity 	report("idiv 3", R_AX | R_CX | R_DX, outregs.eax == (u32)-256);
9050d4c7614SMohammed Gamal }
9060d4c7614SMohammed Gamal 
9076e293cf5SWei Yongjun void test_cbw(void)
9086e293cf5SWei Yongjun {
9096e293cf5SWei Yongjun 	MK_INSN(cbw, "mov $0xFE, %eax \n\t"
9106e293cf5SWei Yongjun 		     "cbw\n\t");
9116e293cf5SWei Yongjun 	MK_INSN(cwde, "mov $0xFFFE, %eax \n\t"
9126e293cf5SWei Yongjun 		      "cwde\n\t");
9136e293cf5SWei Yongjun 
91418253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
91518253fdeSAvi Kivity 
91618253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cbw);
9176055ea1fSAvi Kivity 	report("cbq 1", ~0, outregs.eax == 0xFFFE);
9186e293cf5SWei Yongjun 
91918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cwde);
9206055ea1fSAvi Kivity 	report("cwde 1", ~0, outregs.eax == 0xFFFFFFFE);
9216e293cf5SWei Yongjun }
9226e293cf5SWei Yongjun 
923eacef4e2SWei Yongjun void test_loopcc(void)
924eacef4e2SWei Yongjun {
925eacef4e2SWei Yongjun 	MK_INSN(loop, "mov $10, %ecx\n\t"
926eacef4e2SWei Yongjun 		      "1: inc %eax\n\t"
927eacef4e2SWei Yongjun 		      "loop 1b\n\t");
928eacef4e2SWei Yongjun 
929eacef4e2SWei Yongjun 	MK_INSN(loope, "mov $10, %ecx\n\t"
930eacef4e2SWei Yongjun 		       "mov $1, %eax\n\t"
931eacef4e2SWei Yongjun 		       "1: dec %eax\n\t"
932eacef4e2SWei Yongjun 		       "loope 1b\n\t");
933eacef4e2SWei Yongjun 
934eacef4e2SWei Yongjun 	MK_INSN(loopne, "mov $10, %ecx\n\t"
935eacef4e2SWei Yongjun 		        "mov $5, %eax\n\t"
936eacef4e2SWei Yongjun 		        "1: dec %eax\n\t"
937eacef4e2SWei Yongjun 			"loopne 1b\n\t");
938eacef4e2SWei Yongjun 
93918253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
940eacef4e2SWei Yongjun 
94118253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_loop);
9426055ea1fSAvi Kivity 	report("LOOPcc short 1", R_AX, outregs.eax == 10);
94318253fdeSAvi Kivity 
94418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_loope);
9456055ea1fSAvi Kivity 	report("LOOPcc short 2", R_AX | R_CX,
9466055ea1fSAvi Kivity 	       outregs.eax == -1 && outregs.ecx == 8);
947eacef4e2SWei Yongjun 
94818253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_loopne);
9496055ea1fSAvi Kivity 	report("LOOPcc short 3", R_AX | R_CX,
9506055ea1fSAvi Kivity 	       outregs.eax == 0 && outregs.ecx == 5);
951eacef4e2SWei Yongjun }
952eacef4e2SWei Yongjun 
953b274feedSAvi Kivity static void test_das(void)
954b274feedSAvi Kivity {
955b274feedSAvi Kivity     short i;
95681050840SAvi Kivity     u16 nr_fail = 0;
957b274feedSAvi Kivity     static unsigned test_cases[1024] = {
958b274feedSAvi Kivity         0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00,
959b274feedSAvi Kivity         0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01,
960b274feedSAvi Kivity         0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02,
961b274feedSAvi Kivity         0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03,
962b274feedSAvi Kivity         0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04,
963b274feedSAvi Kivity         0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05,
964b274feedSAvi Kivity         0x06000606, 0x8701a606, 0x56100006, 0x9711a006,
965b274feedSAvi Kivity         0x02000707, 0x8301a707, 0x12100107, 0x9311a107,
966b274feedSAvi Kivity         0x02000808, 0x8301a808, 0x12100208, 0x9311a208,
967b274feedSAvi Kivity         0x06000909, 0x8701a909, 0x16100309, 0x9711a309,
968b274feedSAvi Kivity         0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a,
969b274feedSAvi Kivity         0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b,
970b274feedSAvi Kivity         0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c,
971b274feedSAvi Kivity         0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d,
972b274feedSAvi Kivity         0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e,
973b274feedSAvi Kivity         0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f,
974b274feedSAvi Kivity         0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10,
975b274feedSAvi Kivity         0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11,
976b274feedSAvi Kivity         0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12,
977b274feedSAvi Kivity         0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13,
978b274feedSAvi Kivity         0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14,
979b274feedSAvi Kivity         0x02001515, 0x8301b515, 0x16100f15, 0x9711af15,
980b274feedSAvi Kivity         0x02001616, 0x8301b616, 0x12101016, 0x9311b016,
981b274feedSAvi Kivity         0x06001717, 0x8701b717, 0x16101117, 0x9711b117,
982b274feedSAvi Kivity         0x06001818, 0x8701b818, 0x16101218, 0x9711b218,
983b274feedSAvi Kivity         0x02001919, 0x8301b919, 0x12101319, 0x9311b319,
984b274feedSAvi Kivity         0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a,
985b274feedSAvi Kivity         0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b,
986b274feedSAvi Kivity         0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c,
987b274feedSAvi Kivity         0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d,
988b274feedSAvi Kivity         0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e,
989b274feedSAvi Kivity         0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f,
990b274feedSAvi Kivity         0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20,
991b274feedSAvi Kivity         0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21,
992b274feedSAvi Kivity         0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22,
993b274feedSAvi Kivity         0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23,
994b274feedSAvi Kivity         0x06002424, 0x8301c424, 0x16101e24, 0x9711be24,
995b274feedSAvi Kivity         0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25,
996b274feedSAvi Kivity         0x02002626, 0x8701c626, 0x12102026, 0x9711c026,
997b274feedSAvi Kivity         0x06002727, 0x8301c727, 0x16102127, 0x9311c127,
998b274feedSAvi Kivity         0x06002828, 0x8301c828, 0x16102228, 0x9311c228,
999b274feedSAvi Kivity         0x02002929, 0x8701c929, 0x12102329, 0x9711c329,
1000b274feedSAvi Kivity         0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a,
1001b274feedSAvi Kivity         0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b,
1002b274feedSAvi Kivity         0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c,
1003b274feedSAvi Kivity         0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d,
1004b274feedSAvi Kivity         0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e,
1005b274feedSAvi Kivity         0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f,
1006b274feedSAvi Kivity         0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30,
1007b274feedSAvi Kivity         0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31,
1008b274feedSAvi Kivity         0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32,
1009b274feedSAvi Kivity         0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33,
1010b274feedSAvi Kivity         0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34,
1011b274feedSAvi Kivity         0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35,
1012b274feedSAvi Kivity         0x06003636, 0x8301d636, 0x16103036, 0x9311d036,
1013b274feedSAvi Kivity         0x02003737, 0x8701d737, 0x12103137, 0x9711d137,
1014b274feedSAvi Kivity         0x02003838, 0x8701d838, 0x12103238, 0x9711d238,
1015b274feedSAvi Kivity         0x06003939, 0x8301d939, 0x16103339, 0x9311d339,
1016b274feedSAvi Kivity         0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a,
1017b274feedSAvi Kivity         0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b,
1018b274feedSAvi Kivity         0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c,
1019b274feedSAvi Kivity         0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d,
1020b274feedSAvi Kivity         0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e,
1021b274feedSAvi Kivity         0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f,
1022b274feedSAvi Kivity         0x02004040, 0x8301e040, 0x16103a40, 0x9311da40,
1023b274feedSAvi Kivity         0x06004141, 0x8701e141, 0x12103b41, 0x9711db41,
1024b274feedSAvi Kivity         0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42,
1025b274feedSAvi Kivity         0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43,
1026b274feedSAvi Kivity         0x06004444, 0x8701e444, 0x12103e44, 0x9711de44,
1027b274feedSAvi Kivity         0x02004545, 0x8301e545, 0x16103f45, 0x9311df45,
1028b274feedSAvi Kivity         0x02004646, 0x8301e646, 0x12104046, 0x9311e046,
1029b274feedSAvi Kivity         0x06004747, 0x8701e747, 0x16104147, 0x9711e147,
1030b274feedSAvi Kivity         0x06004848, 0x8701e848, 0x16104248, 0x9711e248,
1031b274feedSAvi Kivity         0x02004949, 0x8301e949, 0x12104349, 0x9311e349,
1032b274feedSAvi Kivity         0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a,
1033b274feedSAvi Kivity         0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b,
1034b274feedSAvi Kivity         0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c,
1035b274feedSAvi Kivity         0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d,
1036b274feedSAvi Kivity         0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e,
1037b274feedSAvi Kivity         0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f,
1038b274feedSAvi Kivity         0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50,
1039b274feedSAvi Kivity         0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51,
1040b274feedSAvi Kivity         0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52,
1041b274feedSAvi Kivity         0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53,
1042b274feedSAvi Kivity         0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54,
1043b274feedSAvi Kivity         0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55,
1044b274feedSAvi Kivity         0x06005656, 0x8701f656, 0x16105056, 0x9711f056,
1045b274feedSAvi Kivity         0x02005757, 0x8301f757, 0x12105157, 0x9311f157,
1046b274feedSAvi Kivity         0x02005858, 0x8301f858, 0x12105258, 0x9311f258,
1047b274feedSAvi Kivity         0x06005959, 0x8701f959, 0x16105359, 0x9711f359,
1048b274feedSAvi Kivity         0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a,
1049b274feedSAvi Kivity         0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b,
1050b274feedSAvi Kivity         0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c,
1051b274feedSAvi Kivity         0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d,
1052b274feedSAvi Kivity         0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e,
1053b274feedSAvi Kivity         0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f,
1054b274feedSAvi Kivity         0x06006060, 0x47010060, 0x16105a60, 0x9711fa60,
1055b274feedSAvi Kivity         0x02006161, 0x03010161, 0x12105b61, 0x9311fb61,
1056b274feedSAvi Kivity         0x02006262, 0x03010262, 0x16105c62, 0x9711fc62,
1057b274feedSAvi Kivity         0x06006363, 0x07010363, 0x12105d63, 0x9311fd63,
1058b274feedSAvi Kivity         0x02006464, 0x03010464, 0x12105e64, 0x9311fe64,
1059b274feedSAvi Kivity         0x06006565, 0x07010565, 0x16105f65, 0x9711ff65,
1060b274feedSAvi Kivity         0x06006666, 0x07010666, 0x16106066, 0x57110066,
1061b274feedSAvi Kivity         0x02006767, 0x03010767, 0x12106167, 0x13110167,
1062b274feedSAvi Kivity         0x02006868, 0x03010868, 0x12106268, 0x13110268,
1063b274feedSAvi Kivity         0x06006969, 0x07010969, 0x16106369, 0x17110369,
1064b274feedSAvi Kivity         0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a,
1065b274feedSAvi Kivity         0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b,
1066b274feedSAvi Kivity         0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c,
1067b274feedSAvi Kivity         0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d,
1068b274feedSAvi Kivity         0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e,
1069b274feedSAvi Kivity         0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f,
1070b274feedSAvi Kivity         0x02007070, 0x03011070, 0x16106a70, 0x17110a70,
1071b274feedSAvi Kivity         0x06007171, 0x07011171, 0x12106b71, 0x13110b71,
1072b274feedSAvi Kivity         0x06007272, 0x07011272, 0x16106c72, 0x17110c72,
1073b274feedSAvi Kivity         0x02007373, 0x03011373, 0x12106d73, 0x13110d73,
1074b274feedSAvi Kivity         0x06007474, 0x07011474, 0x12106e74, 0x13110e74,
1075b274feedSAvi Kivity         0x02007575, 0x03011575, 0x16106f75, 0x17110f75,
1076b274feedSAvi Kivity         0x02007676, 0x03011676, 0x12107076, 0x13111076,
1077b274feedSAvi Kivity         0x06007777, 0x07011777, 0x16107177, 0x17111177,
1078b274feedSAvi Kivity         0x06007878, 0x07011878, 0x16107278, 0x17111278,
1079b274feedSAvi Kivity         0x02007979, 0x03011979, 0x12107379, 0x13111379,
1080b274feedSAvi Kivity         0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a,
1081b274feedSAvi Kivity         0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b,
1082b274feedSAvi Kivity         0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c,
1083b274feedSAvi Kivity         0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d,
1084b274feedSAvi Kivity         0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e,
1085b274feedSAvi Kivity         0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f,
1086b274feedSAvi Kivity         0x82008080, 0x03012080, 0x12107a80, 0x13111a80,
1087b274feedSAvi Kivity         0x86008181, 0x07012181, 0x16107b81, 0x17111b81,
1088b274feedSAvi Kivity         0x86008282, 0x07012282, 0x12107c82, 0x13111c82,
1089b274feedSAvi Kivity         0x82008383, 0x03012383, 0x16107d83, 0x17111d83,
1090b274feedSAvi Kivity         0x86008484, 0x07012484, 0x16107e84, 0x17111e84,
1091b274feedSAvi Kivity         0x82008585, 0x03012585, 0x12107f85, 0x13111f85,
1092b274feedSAvi Kivity         0x82008686, 0x03012686, 0x92108086, 0x13112086,
1093b274feedSAvi Kivity         0x86008787, 0x07012787, 0x96108187, 0x17112187,
1094b274feedSAvi Kivity         0x86008888, 0x07012888, 0x96108288, 0x17112288,
1095b274feedSAvi Kivity         0x82008989, 0x03012989, 0x92108389, 0x13112389,
1096b274feedSAvi Kivity         0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a,
1097b274feedSAvi Kivity         0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b,
1098b274feedSAvi Kivity         0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c,
1099b274feedSAvi Kivity         0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d,
1100b274feedSAvi Kivity         0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e,
1101b274feedSAvi Kivity         0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f,
1102b274feedSAvi Kivity         0x86009090, 0x07013090, 0x92108a90, 0x13112a90,
1103b274feedSAvi Kivity         0x82009191, 0x03013191, 0x96108b91, 0x17112b91,
1104b274feedSAvi Kivity         0x82009292, 0x03013292, 0x92108c92, 0x13112c92,
1105b274feedSAvi Kivity         0x86009393, 0x07013393, 0x96108d93, 0x17112d93,
1106b274feedSAvi Kivity         0x82009494, 0x03013494, 0x96108e94, 0x17112e94,
1107b274feedSAvi Kivity         0x86009595, 0x07013595, 0x92108f95, 0x13112f95,
1108b274feedSAvi Kivity         0x86009696, 0x07013696, 0x96109096, 0x17113096,
1109b274feedSAvi Kivity         0x82009797, 0x03013797, 0x92109197, 0x13113197,
1110b274feedSAvi Kivity         0x82009898, 0x03013898, 0x92109298, 0x13113298,
1111b274feedSAvi Kivity         0x86009999, 0x07013999, 0x96109399, 0x17113399,
1112b274feedSAvi Kivity         0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a,
1113b274feedSAvi Kivity         0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b,
1114b274feedSAvi Kivity         0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c,
1115b274feedSAvi Kivity         0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d,
1116b274feedSAvi Kivity         0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e,
1117b274feedSAvi Kivity         0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f,
1118b274feedSAvi Kivity         0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0,
1119b274feedSAvi Kivity         0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1,
1120b274feedSAvi Kivity         0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2,
1121b274feedSAvi Kivity         0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3,
1122b274feedSAvi Kivity         0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4,
1123b274feedSAvi Kivity         0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5,
1124b274feedSAvi Kivity         0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6,
1125b274feedSAvi Kivity         0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7,
1126b274feedSAvi Kivity         0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8,
1127b274feedSAvi Kivity         0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9,
1128b274feedSAvi Kivity         0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa,
1129b274feedSAvi Kivity         0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab,
1130b274feedSAvi Kivity         0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac,
1131b274feedSAvi Kivity         0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad,
1132b274feedSAvi Kivity         0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae,
1133b274feedSAvi Kivity         0x130049af, 0x130149af, 0x131049af, 0x131149af,
1134b274feedSAvi Kivity         0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0,
1135b274feedSAvi Kivity         0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1,
1136b274feedSAvi Kivity         0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2,
1137b274feedSAvi Kivity         0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3,
1138b274feedSAvi Kivity         0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4,
1139b274feedSAvi Kivity         0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5,
1140b274feedSAvi Kivity         0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6,
1141b274feedSAvi Kivity         0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7,
1142b274feedSAvi Kivity         0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8,
1143b274feedSAvi Kivity         0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9,
1144b274feedSAvi Kivity         0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba,
1145b274feedSAvi Kivity         0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb,
1146b274feedSAvi Kivity         0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc,
1147b274feedSAvi Kivity         0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd,
1148b274feedSAvi Kivity         0x130058be, 0x130158be, 0x131058be, 0x131158be,
1149b274feedSAvi Kivity         0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf,
1150b274feedSAvi Kivity         0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0,
1151b274feedSAvi Kivity         0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1,
1152b274feedSAvi Kivity         0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2,
1153b274feedSAvi Kivity         0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3,
1154b274feedSAvi Kivity         0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4,
1155b274feedSAvi Kivity         0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5,
1156b274feedSAvi Kivity         0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6,
1157b274feedSAvi Kivity         0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7,
1158b274feedSAvi Kivity         0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8,
1159b274feedSAvi Kivity         0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9,
1160b274feedSAvi Kivity         0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca,
1161b274feedSAvi Kivity         0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb,
1162b274feedSAvi Kivity         0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc,
1163b274feedSAvi Kivity         0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd,
1164b274feedSAvi Kivity         0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce,
1165b274feedSAvi Kivity         0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf,
1166b274feedSAvi Kivity         0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0,
1167b274feedSAvi Kivity         0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1,
1168b274feedSAvi Kivity         0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2,
1169b274feedSAvi Kivity         0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3,
1170b274feedSAvi Kivity         0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4,
1171b274feedSAvi Kivity         0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5,
1172b274feedSAvi Kivity         0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6,
1173b274feedSAvi Kivity         0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7,
1174b274feedSAvi Kivity         0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8,
1175b274feedSAvi Kivity         0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9,
1176b274feedSAvi Kivity         0x170074da, 0x170174da, 0x171074da, 0x171174da,
1177b274feedSAvi Kivity         0x130075db, 0x130175db, 0x131075db, 0x131175db,
1178b274feedSAvi Kivity         0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc,
1179b274feedSAvi Kivity         0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd,
1180b274feedSAvi Kivity         0x170078de, 0x170178de, 0x171078de, 0x171178de,
1181b274feedSAvi Kivity         0x130079df, 0x130179df, 0x131079df, 0x131179df,
1182b274feedSAvi Kivity         0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0,
1183b274feedSAvi Kivity         0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1,
1184b274feedSAvi Kivity         0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2,
1185b274feedSAvi Kivity         0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3,
1186b274feedSAvi Kivity         0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4,
1187b274feedSAvi Kivity         0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5,
1188b274feedSAvi Kivity         0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6,
1189b274feedSAvi Kivity         0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7,
1190b274feedSAvi Kivity         0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8,
1191b274feedSAvi Kivity         0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9,
1192b274feedSAvi Kivity         0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea,
1193b274feedSAvi Kivity         0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb,
1194b274feedSAvi Kivity         0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec,
1195b274feedSAvi Kivity         0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed,
1196b274feedSAvi Kivity         0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee,
1197b274feedSAvi Kivity         0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef,
1198b274feedSAvi Kivity         0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0,
1199b274feedSAvi Kivity         0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1,
1200b274feedSAvi Kivity         0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2,
1201b274feedSAvi Kivity         0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3,
1202b274feedSAvi Kivity         0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4,
1203b274feedSAvi Kivity         0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5,
1204b274feedSAvi Kivity         0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6,
1205b274feedSAvi Kivity         0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7,
1206b274feedSAvi Kivity         0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8,
1207b274feedSAvi Kivity         0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9,
1208b274feedSAvi Kivity         0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa,
1209b274feedSAvi Kivity         0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb,
1210b274feedSAvi Kivity         0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc,
1211b274feedSAvi Kivity         0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd,
1212b274feedSAvi Kivity         0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe,
1213b274feedSAvi Kivity         0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff,
1214b274feedSAvi Kivity     };
1215b274feedSAvi Kivity 
1216b274feedSAvi Kivity     MK_INSN(das, "das");
1217b274feedSAvi Kivity 
121818253fdeSAvi Kivity     inregs = (struct regs){ 0 };
121918253fdeSAvi Kivity 
1220b274feedSAvi Kivity     for (i = 0; i < 1024; ++i) {
1221b274feedSAvi Kivity         unsigned tmp = test_cases[i];
1222b274feedSAvi Kivity         inregs.eax = tmp & 0xff;
1223b274feedSAvi Kivity         inregs.eflags = (tmp >> 16) & 0xff;
122418253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_das);
122518253fdeSAvi Kivity 	if (!regs_equal(R_AX)
1226b274feedSAvi Kivity             || outregs.eax != ((tmp >> 8) & 0xff)
1227b274feedSAvi Kivity             || (outregs.eflags & 0xff) != (tmp >> 24)) {
122881050840SAvi Kivity 	    ++nr_fail;
122981050840SAvi Kivity 	    break;
1230b274feedSAvi Kivity         }
1231b274feedSAvi Kivity     }
12326055ea1fSAvi Kivity     report("DAS", ~0, nr_fail == 0);
1233b274feedSAvi Kivity }
1234b274feedSAvi Kivity 
12350cbd5b06SMohammed Gamal void test_cwd_cdq()
12360cbd5b06SMohammed Gamal {
12370cbd5b06SMohammed Gamal 	/* Sign-bit set */
12380cbd5b06SMohammed Gamal 	MK_INSN(cwd_1, "mov $0x8000, %ax\n\t"
12390cbd5b06SMohammed Gamal 		       "cwd\n\t");
12400cbd5b06SMohammed Gamal 
12410cbd5b06SMohammed Gamal 	/* Sign-bit not set */
12420cbd5b06SMohammed Gamal 	MK_INSN(cwd_2, "mov $0x1000, %ax\n\t"
12430cbd5b06SMohammed Gamal 		       "cwd\n\t");
12440cbd5b06SMohammed Gamal 
12450cbd5b06SMohammed Gamal 	/* Sign-bit set */
12460cbd5b06SMohammed Gamal 	MK_INSN(cdq_1, "mov $0x80000000, %eax\n\t"
12470cbd5b06SMohammed Gamal 		       "cdq\n\t");
12480cbd5b06SMohammed Gamal 
12490cbd5b06SMohammed Gamal 	/* Sign-bit not set */
12500cbd5b06SMohammed Gamal 	MK_INSN(cdq_2, "mov $0x10000000, %eax\n\t"
12510cbd5b06SMohammed Gamal 		       "cdq\n\t");
12520cbd5b06SMohammed Gamal 
125318253fdeSAvi Kivity 	inregs = (struct regs){ 0 };
125418253fdeSAvi Kivity 
125518253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cwd_1);
12566055ea1fSAvi Kivity 	report("cwd 1", R_AX | R_DX,
12576055ea1fSAvi Kivity 	       outregs.eax == 0x8000 && outregs.edx == 0xffff);
12580cbd5b06SMohammed Gamal 
125918253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cwd_2);
12606055ea1fSAvi Kivity 	report("cwd 2", R_AX | R_DX,
12616055ea1fSAvi Kivity 	       outregs.eax == 0x1000 && outregs.edx == 0);
12620cbd5b06SMohammed Gamal 
126318253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cdq_1);
12646055ea1fSAvi Kivity 	report("cdq 1", R_AX | R_DX,
12656055ea1fSAvi Kivity 	       outregs.eax == 0x80000000 && outregs.edx == 0xffffffff);
12660cbd5b06SMohammed Gamal 
126718253fdeSAvi Kivity 	exec_in_big_real_mode(&insn_cdq_2);
12686055ea1fSAvi Kivity 	report("cdq 2", R_AX | R_DX,
12696055ea1fSAvi Kivity 	       outregs.eax == 0x10000000 && outregs.edx == 0);
12700cbd5b06SMohammed Gamal }
12710cbd5b06SMohammed Gamal 
127237f51a4aSWei Yongjun static struct {
127337f51a4aSWei Yongjun         void *address;
127437f51a4aSWei Yongjun         unsigned short sel;
127537f51a4aSWei Yongjun } __attribute__((packed)) desc = {
127637f51a4aSWei Yongjun 	(void *)0x1234,
127737f51a4aSWei Yongjun 	0x10,
127837f51a4aSWei Yongjun };
127937f51a4aSWei Yongjun 
128037f51a4aSWei Yongjun void test_lds_lss()
128137f51a4aSWei Yongjun {
128237f51a4aSWei Yongjun 	inregs = (struct regs){ .ebx = (unsigned long)&desc };
128337f51a4aSWei Yongjun 
128437f51a4aSWei Yongjun 	MK_INSN(lds, "push %ds\n\t"
128537f51a4aSWei Yongjun 		     "lds (%ebx), %eax\n\t"
128637f51a4aSWei Yongjun 		     "mov %ds, %ebx\n\t"
128737f51a4aSWei Yongjun 		     "pop %ds\n\t");
128837f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_lds);
128937f51a4aSWei Yongjun 	report("lds", R_AX | R_BX,
129037f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
129137f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
129237f51a4aSWei Yongjun 
129337f51a4aSWei Yongjun 	MK_INSN(les, "push %es\n\t"
129437f51a4aSWei Yongjun 		     "les (%ebx), %eax\n\t"
129537f51a4aSWei Yongjun 		     "mov %es, %ebx\n\t"
129637f51a4aSWei Yongjun 		     "pop %es\n\t");
129737f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_les);
129837f51a4aSWei Yongjun 	report("les", R_AX | R_BX,
129937f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
130037f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
130137f51a4aSWei Yongjun 
130237f51a4aSWei Yongjun 	MK_INSN(lfs, "push %fs\n\t"
130337f51a4aSWei Yongjun 		     "lfs (%ebx), %eax\n\t"
130437f51a4aSWei Yongjun 		     "mov %fs, %ebx\n\t"
130537f51a4aSWei Yongjun 		     "pop %fs\n\t");
130637f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_lfs);
130737f51a4aSWei Yongjun 	report("lfs", R_AX | R_BX,
130837f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
130937f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
131037f51a4aSWei Yongjun 
131137f51a4aSWei Yongjun 	MK_INSN(lgs, "push %gs\n\t"
131237f51a4aSWei Yongjun 		     "lgs (%ebx), %eax\n\t"
131337f51a4aSWei Yongjun 		     "mov %gs, %ebx\n\t"
131437f51a4aSWei Yongjun 		     "pop %gs\n\t");
131537f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_lgs);
131637f51a4aSWei Yongjun 	report("lgs", R_AX | R_BX,
131737f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
131837f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
131937f51a4aSWei Yongjun 
132037f51a4aSWei Yongjun 	MK_INSN(lss, "push %ss\n\t"
132137f51a4aSWei Yongjun 		     "lss (%ebx), %eax\n\t"
132237f51a4aSWei Yongjun 		     "mov %ss, %ebx\n\t"
132337f51a4aSWei Yongjun 		     "pop %ss\n\t");
132437f51a4aSWei Yongjun 	exec_in_big_real_mode(&insn_lss);
132537f51a4aSWei Yongjun 	report("lss", R_AX | R_BX,
132637f51a4aSWei Yongjun 		outregs.eax == (unsigned long)desc.address &&
132737f51a4aSWei Yongjun 		outregs.ebx == desc.sel);
132837f51a4aSWei Yongjun }
132937f51a4aSWei Yongjun 
1330b1c7c575SWei Yongjun void test_jcxz(void)
1331b1c7c575SWei Yongjun {
1332b1c7c575SWei Yongjun 	MK_INSN(jcxz1, "jcxz 1f\n\t"
1333b1c7c575SWei Yongjun 		       "mov $0x1234, %eax\n\t"
1334b1c7c575SWei Yongjun 		       "1:\n\t");
1335b1c7c575SWei Yongjun 	MK_INSN(jcxz2, "mov $0x100, %ecx\n\t"
1336b1c7c575SWei Yongjun 		       "jcxz 1f\n\t"
1337b1c7c575SWei Yongjun 		       "mov $0x1234, %eax\n\t"
1338b1c7c575SWei Yongjun 		       "mov $0, %ecx\n\t"
1339b1c7c575SWei Yongjun 		       "1:\n\t");
1340b1c7c575SWei Yongjun 	MK_INSN(jcxz3, "mov $0x10000, %ecx\n\t"
1341b1c7c575SWei Yongjun 		       "jcxz 1f\n\t"
1342b1c7c575SWei Yongjun 		       "mov $0x1234, %eax\n\t"
1343b1c7c575SWei Yongjun 		       "1:\n\t");
1344b1c7c575SWei Yongjun 	MK_INSN(jecxz1, "jecxz 1f\n\t"
1345b1c7c575SWei Yongjun 			"mov $0x1234, %eax\n\t"
1346b1c7c575SWei Yongjun 			"1:\n\t");
1347b1c7c575SWei Yongjun 	MK_INSN(jecxz2, "mov $0x10000, %ecx\n\t"
1348b1c7c575SWei Yongjun 			"jecxz 1f\n\t"
1349b1c7c575SWei Yongjun 			"mov $0x1234, %eax\n\t"
1350b1c7c575SWei Yongjun 			"mov $0, %ecx\n\t"
1351b1c7c575SWei Yongjun 			"1:\n\t");
1352b1c7c575SWei Yongjun 
1353b1c7c575SWei Yongjun 	inregs = (struct regs){ 0 };
1354b1c7c575SWei Yongjun 
1355b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jcxz1);
1356b1c7c575SWei Yongjun 	report("jcxz short 1", 0, 1);
1357b1c7c575SWei Yongjun 
1358b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jcxz2);
1359b1c7c575SWei Yongjun 	report("jcxz short 2", R_AX, outregs.eax == 0x1234);
1360b1c7c575SWei Yongjun 
1361b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jcxz3);
1362b1c7c575SWei Yongjun 	report("jcxz short 3", R_CX, outregs.ecx == 0x10000);
1363b1c7c575SWei Yongjun 
1364b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jecxz1);
1365b1c7c575SWei Yongjun 	report("jecxz short 1", 0, 1);
1366b1c7c575SWei Yongjun 
1367b1c7c575SWei Yongjun 	exec_in_big_real_mode(&insn_jecxz2);
1368b1c7c575SWei Yongjun 	report("jecxz short 2", R_AX, outregs.eax == 0x1234);
1369b1c7c575SWei Yongjun }
1370b1c7c575SWei Yongjun 
13718f578e98SAvi Kivity static void test_cpuid(void)
13728f578e98SAvi Kivity {
13738f578e98SAvi Kivity     MK_INSN(cpuid, "cpuid");
13748f578e98SAvi Kivity     unsigned function = 0x1234;
13758f578e98SAvi Kivity     unsigned eax, ebx, ecx, edx;
13768f578e98SAvi Kivity 
13778f578e98SAvi Kivity     inregs.eax = eax = function;
1378*18ba9083SGleb Natapov     inregs.ecx = ecx = 0;
13798f578e98SAvi Kivity     asm("cpuid" : "+a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx));
13808f578e98SAvi Kivity     exec_in_big_real_mode(&insn_cpuid);
13818f578e98SAvi Kivity     report("cpuid", R_AX|R_BX|R_CX|R_DX,
13828f578e98SAvi Kivity 	   outregs.eax == eax && outregs.ebx == ebx
13838f578e98SAvi Kivity 	   && outregs.ecx == ecx && outregs.edx == edx);
13848f578e98SAvi Kivity }
13858f578e98SAvi Kivity 
1386ed93f43bSAvi Kivity static void test_ss_base_for_esp_ebp(void)
1387ed93f43bSAvi Kivity {
1388ed93f43bSAvi Kivity     MK_INSN(ssrel1, "mov %ss, %ax; mov %bx, %ss; movl (%ebp), %ebx; mov %ax, %ss");
1389ed93f43bSAvi Kivity     MK_INSN(ssrel2, "mov %ss, %ax; mov %bx, %ss; movl (%ebp,%edi,8), %ebx; mov %ax, %ss");
1390ed93f43bSAvi Kivity     static unsigned array[] = { 0x12345678, 0, 0, 0, 0x87654321 };
1391ed93f43bSAvi Kivity 
1392ed93f43bSAvi Kivity     inregs.ebx = 1;
1393ed93f43bSAvi Kivity     inregs.ebp = (unsigned)array;
1394ed93f43bSAvi Kivity     exec_in_big_real_mode(&insn_ssrel1);
1395ed93f43bSAvi Kivity     report("ss relative addressing (1)", R_AX | R_BX, outregs.ebx == 0x87654321);
1396ed93f43bSAvi Kivity     inregs.ebx = 1;
1397ed93f43bSAvi Kivity     inregs.ebp = (unsigned)array;
1398ed93f43bSAvi Kivity     inregs.edi = 0;
1399ed93f43bSAvi Kivity     exec_in_big_real_mode(&insn_ssrel2);
1400ed93f43bSAvi Kivity     report("ss relative addressing (2)", R_AX | R_BX, outregs.ebx == 0x87654321);
1401ed93f43bSAvi Kivity }
1402ed93f43bSAvi Kivity 
1403c2281fa4SAvi Kivity static void test_sgdt_sidt(void)
1404c2281fa4SAvi Kivity {
1405c2281fa4SAvi Kivity     MK_INSN(sgdt, "sgdtw (%eax)");
1406c2281fa4SAvi Kivity     MK_INSN(sidt, "sidtw (%eax)");
1407c2281fa4SAvi Kivity     unsigned x, y;
1408c2281fa4SAvi Kivity 
1409c2281fa4SAvi Kivity     inregs.eax = (unsigned)&y;
1410c2281fa4SAvi Kivity     asm volatile("sgdtw %0" : "=m"(x));
1411c2281fa4SAvi Kivity     exec_in_big_real_mode(&insn_sgdt);
1412c2281fa4SAvi Kivity     report("sgdt", 0, x == y);
1413c2281fa4SAvi Kivity 
1414c2281fa4SAvi Kivity     inregs.eax = (unsigned)&y;
1415c2281fa4SAvi Kivity     asm volatile("sidtw %0" : "=m"(x));
1416c2281fa4SAvi Kivity     exec_in_big_real_mode(&insn_sidt);
1417c2281fa4SAvi Kivity     report("sidt", 0, x == y);
1418c2281fa4SAvi Kivity }
1419c2281fa4SAvi Kivity 
142088b6dac4SPaolo Bonzini static void test_sahf(void)
142188b6dac4SPaolo Bonzini {
142288b6dac4SPaolo Bonzini     MK_INSN(sahf, "sahf; pushfw; mov (%esp), %al; popfw");
142388b6dac4SPaolo Bonzini 
142488b6dac4SPaolo Bonzini     inregs.eax = 0xfd00;
142588b6dac4SPaolo Bonzini     exec_in_big_real_mode(&insn_sahf);
142688b6dac4SPaolo Bonzini     report("sahf", R_AX, outregs.eax == (inregs.eax | 0xd7));
142788b6dac4SPaolo Bonzini }
142888b6dac4SPaolo Bonzini 
14297ae3645aSAvi Kivity static void test_lahf(void)
14307ae3645aSAvi Kivity {
14317ae3645aSAvi Kivity     MK_INSN(lahf, "pushfw; mov %al, (%esp); popfw; lahf");
14327ae3645aSAvi Kivity 
14337ae3645aSAvi Kivity     inregs.eax = 0xc7;
14347ae3645aSAvi Kivity     exec_in_big_real_mode(&insn_lahf);
14357ae3645aSAvi Kivity     report("lahf", R_AX, (outregs.eax >> 8) == inregs.eax);
14367ae3645aSAvi Kivity }
14377ae3645aSAvi Kivity 
1438fd9ea640SAvi Kivity static void test_movzx_movsx(void)
1439fd9ea640SAvi Kivity {
1440fd9ea640SAvi Kivity     MK_INSN(movsx, "movsx %al, %ebx");
1441fd9ea640SAvi Kivity     MK_INSN(movzx, "movzx %al, %ebx");
14423013e079SGleb Natapov     MK_INSN(movzsah, "movsx %ah, %ebx");
14433013e079SGleb Natapov     MK_INSN(movzxah, "movzx %ah, %ebx");
1444fd9ea640SAvi Kivity 
1445fd9ea640SAvi Kivity     inregs.eax = 0x1234569c;
14463013e079SGleb Natapov     inregs.esp = 0xffff;
1447fd9ea640SAvi Kivity     exec_in_big_real_mode(&insn_movsx);
1448fd9ea640SAvi Kivity     report("movsx", R_BX, outregs.ebx == (signed char)inregs.eax);
1449fd9ea640SAvi Kivity     exec_in_big_real_mode(&insn_movzx);
1450fd9ea640SAvi Kivity     report("movzx", R_BX, outregs.ebx == (unsigned char)inregs.eax);
14513013e079SGleb Natapov     exec_in_big_real_mode(&insn_movzsah);
14523013e079SGleb Natapov     report("movsx ah", R_BX, outregs.ebx == (signed char)(inregs.eax>>8));
14533013e079SGleb Natapov     exec_in_big_real_mode(&insn_movzxah);
14543013e079SGleb Natapov     report("movzx ah", R_BX, outregs.ebx == (unsigned char)(inregs.eax >> 8));
1455fd9ea640SAvi Kivity }
1456fd9ea640SAvi Kivity 
1457b493b2e8SAvi Kivity static void test_bswap(void)
1458b493b2e8SAvi Kivity {
1459b493b2e8SAvi Kivity     MK_INSN(bswap, "bswap %ecx");
1460b493b2e8SAvi Kivity 
1461b493b2e8SAvi Kivity     inregs.ecx = 0x12345678;
1462b493b2e8SAvi Kivity     exec_in_big_real_mode(&insn_bswap);
1463b493b2e8SAvi Kivity     report("bswap", R_CX, outregs.ecx == 0x78563412);
1464b493b2e8SAvi Kivity }
1465b493b2e8SAvi Kivity 
14668cd86387SGleb Natapov static void test_aad(void)
14678cd86387SGleb Natapov {
14688cd86387SGleb Natapov     MK_INSN(aad, "aad");
14698cd86387SGleb Natapov 
14708cd86387SGleb Natapov     inregs.eax = 0x12345678;
14718cd86387SGleb Natapov     exec_in_big_real_mode(&insn_aad);
14728cd86387SGleb Natapov     report("aad", R_AX, outregs.eax == 0x123400d4);
14738cd86387SGleb Natapov }
14748cd86387SGleb Natapov 
14752a9b5718SPaolo Bonzini static void test_aam(void)
14762a9b5718SPaolo Bonzini {
14772a9b5718SPaolo Bonzini     MK_INSN(aam, "aam");
14782a9b5718SPaolo Bonzini 
14792a9b5718SPaolo Bonzini     inregs.eax = 0x76543210;
14802a9b5718SPaolo Bonzini     exec_in_big_real_mode(&insn_aam);
14812a9b5718SPaolo Bonzini     report("aam", R_AX, outregs.eax == 0x76540106);
14822a9b5718SPaolo Bonzini }
14832a9b5718SPaolo Bonzini 
14842a9b5718SPaolo Bonzini static void test_xlat(void)
14852a9b5718SPaolo Bonzini {
14862a9b5718SPaolo Bonzini     MK_INSN(xlat, "xlat");
14872a9b5718SPaolo Bonzini     u8 table[256];
14882a9b5718SPaolo Bonzini     int i;
14892a9b5718SPaolo Bonzini 
14902a9b5718SPaolo Bonzini     for (i = 0; i < 256; i++) {
14912a9b5718SPaolo Bonzini         table[i] = i + 1;
14922a9b5718SPaolo Bonzini     }
14932a9b5718SPaolo Bonzini 
14942a9b5718SPaolo Bonzini     inregs.eax = 0x89abcdef;
14952a9b5718SPaolo Bonzini     inregs.ebx = (u32)table;
14962a9b5718SPaolo Bonzini     exec_in_big_real_mode(&insn_xlat);
14972a9b5718SPaolo Bonzini     report("xlat", R_AX, outregs.eax == 0x89abcdf0);
14982a9b5718SPaolo Bonzini }
14992a9b5718SPaolo Bonzini 
15002a9b5718SPaolo Bonzini static void test_salc(void)
15012a9b5718SPaolo Bonzini {
15022a9b5718SPaolo Bonzini     MK_INSN(clc_salc, "clc; .byte 0xd6");
15032a9b5718SPaolo Bonzini     MK_INSN(stc_salc, "stc; .byte 0xd6");
15042a9b5718SPaolo Bonzini 
15052a9b5718SPaolo Bonzini     inregs.eax = 0x12345678;
15062a9b5718SPaolo Bonzini     exec_in_big_real_mode(&insn_clc_salc);
15072a9b5718SPaolo Bonzini     report("salc (1)", R_AX, outregs.eax == 0x12345600);
15082a9b5718SPaolo Bonzini     exec_in_big_real_mode(&insn_stc_salc);
15092a9b5718SPaolo Bonzini     report("salc (2)", R_AX, outregs.eax == 0x123456ff);
15102a9b5718SPaolo Bonzini }
15112a9b5718SPaolo Bonzini 
15120987db7aSGleb Natapov static void test_fninit(void)
15130987db7aSGleb Natapov {
15140987db7aSGleb Natapov 	u16 fcw = -1, fsw = -1;
15150987db7aSGleb Natapov 	MK_INSN(fninit, "fninit ; fnstsw (%eax) ; fnstcw (%ebx)");
15160987db7aSGleb Natapov 
15170987db7aSGleb Natapov 	inregs.eax = (u32)&fsw;
15180987db7aSGleb Natapov 	inregs.ebx = (u32)&fcw;
15190987db7aSGleb Natapov 
15200987db7aSGleb Natapov 	exec_in_big_real_mode(&insn_fninit);
15210987db7aSGleb Natapov 	report("fninit", 0, fsw == 0 && (fcw & 0x103f) == 0x003f);
15220987db7aSGleb Natapov }
15230987db7aSGleb Natapov 
15241a4c03a0SArthur Chunqi Li static void test_nopl(void)
15251a4c03a0SArthur Chunqi Li {
15261a4c03a0SArthur Chunqi Li 	MK_INSN(nopl1, ".byte 0x90\n\r"); // 1 byte nop
15271a4c03a0SArthur Chunqi Li 	MK_INSN(nopl2, ".byte 0x66, 0x90\n\r"); // 2 bytes nop
15281a4c03a0SArthur Chunqi Li 	MK_INSN(nopl3, ".byte 0x0f, 0x1f, 0x00\n\r"); // 3 bytes nop
15291a4c03a0SArthur Chunqi Li 	MK_INSN(nopl4, ".byte 0x0f, 0x1f, 0x40, 0x00\n\r"); // 4 bytes nop
15301a4c03a0SArthur Chunqi Li 	exec_in_big_real_mode(&insn_nopl1);
15311a4c03a0SArthur Chunqi Li 	exec_in_big_real_mode(&insn_nopl2);
15321a4c03a0SArthur Chunqi Li 	exec_in_big_real_mode(&insn_nopl3);
15331a4c03a0SArthur Chunqi Li 	exec_in_big_real_mode(&insn_nopl4);
15341a4c03a0SArthur Chunqi Li 	report("nopl", 0, 1);
15351a4c03a0SArthur Chunqi Li }
15361a4c03a0SArthur Chunqi Li 
15377d36db35SAvi Kivity void realmode_start(void)
15387d36db35SAvi Kivity {
15397d36db35SAvi Kivity 	test_null();
15407d36db35SAvi Kivity 
15417d36db35SAvi Kivity 	test_shld();
15427d36db35SAvi Kivity 	test_push_pop();
15437d36db35SAvi Kivity 	test_pusha_popa();
15447d36db35SAvi Kivity 	test_mov_imm();
15457d36db35SAvi Kivity 	test_cmp_imm();
15467d36db35SAvi Kivity 	test_add_imm();
15477d36db35SAvi Kivity 	test_sub_imm();
15487d36db35SAvi Kivity 	test_xor_imm();
15497d36db35SAvi Kivity 	test_io();
15507d36db35SAvi Kivity 	test_eflags_insn();
15517d36db35SAvi Kivity 	test_jcc_short();
15527d36db35SAvi Kivity 	test_jcc_near();
15537d36db35SAvi Kivity 	/* test_call() uses short jump so call it after testing jcc */
15547d36db35SAvi Kivity 	test_call();
15557d36db35SAvi Kivity 	/* long jmp test uses call near so test it after testing call */
15567d36db35SAvi Kivity 	test_long_jmp();
15577d36db35SAvi Kivity 	test_xchg();
15587d36db35SAvi Kivity 	test_iret();
155996b9ca1eSMohammed Gamal 	test_int();
1560fa74f8a6SMohammed Gamal 	test_imul();
156159317bd1SMohammed Gamal 	test_mul();
15620d4c7614SMohammed Gamal 	test_div();
15630d4c7614SMohammed Gamal 	test_idiv();
1564eacef4e2SWei Yongjun 	test_loopcc();
15656e293cf5SWei Yongjun 	test_cbw();
15660cbd5b06SMohammed Gamal 	test_cwd_cdq();
1567b274feedSAvi Kivity 	test_das();
156837f51a4aSWei Yongjun 	test_lds_lss();
1569b1c7c575SWei Yongjun 	test_jcxz();
15708f578e98SAvi Kivity 	test_cpuid();
1571ed93f43bSAvi Kivity 	test_ss_base_for_esp_ebp();
1572c2281fa4SAvi Kivity 	test_sgdt_sidt();
15737ae3645aSAvi Kivity 	test_lahf();
157488b6dac4SPaolo Bonzini 	test_sahf();
1575fd9ea640SAvi Kivity 	test_movzx_movsx();
1576b493b2e8SAvi Kivity 	test_bswap();
15778cd86387SGleb Natapov 	test_aad();
15782a9b5718SPaolo Bonzini 	test_aam();
15792a9b5718SPaolo Bonzini 	test_xlat();
15802a9b5718SPaolo Bonzini 	test_salc();
15810987db7aSGleb Natapov 	test_fninit();
15821a4c03a0SArthur Chunqi Li 	test_nopl();
15837d36db35SAvi Kivity 
15847d36db35SAvi Kivity 	exit(0);
15857d36db35SAvi Kivity }
15867d36db35SAvi Kivity 
15877d36db35SAvi Kivity unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff };
15887d36db35SAvi Kivity 
15897d36db35SAvi Kivity struct __attribute__((packed)) {
15907d36db35SAvi Kivity 	unsigned short limit;
15917d36db35SAvi Kivity 	void *base;
15927d36db35SAvi Kivity } r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt };
15937d36db35SAvi Kivity 
15947d36db35SAvi Kivity asm(
15957d36db35SAvi Kivity 	".section .init \n\t"
15967d36db35SAvi Kivity 
15977d36db35SAvi Kivity 	".code32 \n\t"
15987d36db35SAvi Kivity 
15997d36db35SAvi Kivity 	"mb_magic = 0x1BADB002 \n\t"
16007d36db35SAvi Kivity 	"mb_flags = 0x0 \n\t"
16017d36db35SAvi Kivity 
16027d36db35SAvi Kivity 	"# multiboot header \n\t"
16037d36db35SAvi Kivity 	".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t"
16047d36db35SAvi Kivity 
16057d36db35SAvi Kivity 	".globl start \n\t"
16067d36db35SAvi Kivity 	".data \n\t"
16077d36db35SAvi Kivity 	". = . + 4096 \n\t"
16087d36db35SAvi Kivity 	"stacktop: \n\t"
16097d36db35SAvi Kivity 
16107d36db35SAvi Kivity 	".text \n\t"
16117d36db35SAvi Kivity 	"start: \n\t"
16127d36db35SAvi Kivity 	"lgdt r_gdt_descr \n\t"
16137d36db35SAvi Kivity 	"ljmp $8, $1f; 1: \n\t"
16147d36db35SAvi Kivity 	".code16gcc \n\t"
16157d36db35SAvi Kivity 	"mov $16, %eax \n\t"
16167d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
16177d36db35SAvi Kivity 	"mov %ax, %es \n\t"
16187d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
16197d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
16207d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
16217d36db35SAvi Kivity 	"mov %cr0, %eax \n\t"
16227d36db35SAvi Kivity 	"btc $0, %eax \n\t"
16237d36db35SAvi Kivity 	"mov %eax, %cr0 \n\t"
16247d36db35SAvi Kivity 	"ljmp $0, $realmode_entry \n\t"
16257d36db35SAvi Kivity 
16267d36db35SAvi Kivity 	"realmode_entry: \n\t"
16277d36db35SAvi Kivity 
16287d36db35SAvi Kivity 	"xor %ax, %ax \n\t"
16297d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
16307d36db35SAvi Kivity 	"mov %ax, %es \n\t"
16317d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
16327d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
16337d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
16347d36db35SAvi Kivity 	"mov $stacktop, %esp\n\t"
16357d36db35SAvi Kivity 	"ljmp $0, $realmode_start \n\t"
16367d36db35SAvi Kivity 
16377d36db35SAvi Kivity 	".code16gcc \n\t"
16387d36db35SAvi Kivity 	);
1639