xref: /kvm-unit-tests/x86/realmode.c (revision 81050840eceb26bdb1a59cdbd4651e491f3e5090)
17d36db35SAvi Kivity asm(".code16gcc");
27d36db35SAvi Kivity 
37d36db35SAvi Kivity typedef unsigned char u8;
47d36db35SAvi Kivity typedef unsigned short u16;
57d36db35SAvi Kivity typedef unsigned u32;
67d36db35SAvi Kivity typedef unsigned long long u64;
77d36db35SAvi Kivity 
87d36db35SAvi Kivity void test_function(void);
97d36db35SAvi Kivity 
107d36db35SAvi Kivity asm(
117d36db35SAvi Kivity 	"test_function: \n\t"
127d36db35SAvi Kivity 	"mov $0x1234, %eax \n\t"
137d36db35SAvi Kivity 	"ret"
147d36db35SAvi Kivity    );
157d36db35SAvi Kivity 
167d36db35SAvi Kivity static int strlen(const char *str)
177d36db35SAvi Kivity {
187d36db35SAvi Kivity 	int n;
197d36db35SAvi Kivity 
207d36db35SAvi Kivity 	for (n = 0; *str; ++str)
217d36db35SAvi Kivity 		++n;
227d36db35SAvi Kivity 	return n;
237d36db35SAvi Kivity }
247d36db35SAvi Kivity 
257d36db35SAvi Kivity static void print_serial(const char *buf)
267d36db35SAvi Kivity {
277d36db35SAvi Kivity 	unsigned long len = strlen(buf);
287d36db35SAvi Kivity 
297d36db35SAvi Kivity 	asm volatile ("cld; addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1));
307d36db35SAvi Kivity }
317d36db35SAvi Kivity 
327d36db35SAvi Kivity static void exit(int code)
337d36db35SAvi Kivity {
347d36db35SAvi Kivity         asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4));
357d36db35SAvi Kivity }
367d36db35SAvi Kivity 
377d36db35SAvi Kivity struct regs {
387d36db35SAvi Kivity 	u32 eax, ebx, ecx, edx;
397d36db35SAvi Kivity 	u32 esi, edi, esp, ebp;
407d36db35SAvi Kivity 	u32 eip, eflags;
417d36db35SAvi Kivity };
427d36db35SAvi Kivity 
437d36db35SAvi Kivity static u64 gdt[] = {
447d36db35SAvi Kivity 	0,
457d36db35SAvi Kivity 	0x00cf9b000000ffffull, // flat 32-bit code segment
467d36db35SAvi Kivity 	0x00cf93000000ffffull, // flat 32-bit data segment
477d36db35SAvi Kivity };
487d36db35SAvi Kivity 
497d36db35SAvi Kivity static struct {
507d36db35SAvi Kivity 	u16 limit;
517d36db35SAvi Kivity 	void *base;
527d36db35SAvi Kivity } __attribute__((packed)) gdt_descr = {
537d36db35SAvi Kivity 	sizeof(gdt) - 1,
547d36db35SAvi Kivity 	gdt,
557d36db35SAvi Kivity };
567d36db35SAvi Kivity 
57d4dc402cSAvi Kivity struct insn_desc {
58d4dc402cSAvi Kivity     u16 ptr;
59d4dc402cSAvi Kivity     u16 len;
60d4dc402cSAvi Kivity };
61d4dc402cSAvi Kivity 
627d36db35SAvi Kivity static void exec_in_big_real_mode(const struct regs *inregs,
637d36db35SAvi Kivity 				  struct regs *outregs,
64d4dc402cSAvi Kivity 				  struct insn_desc *insn)
657d36db35SAvi Kivity {
667d36db35SAvi Kivity 	unsigned long tmp;
677d36db35SAvi Kivity 	static struct regs save;
687d36db35SAvi Kivity 	int i;
697d36db35SAvi Kivity 	extern u8 test_insn[], test_insn_end[];
707d36db35SAvi Kivity 
71d4dc402cSAvi Kivity 	for (i = 0; i < insn->len; ++i)
72d4dc402cSAvi Kivity 	    test_insn[i] = ((u8 *)(unsigned long)insn->ptr)[i];
737d36db35SAvi Kivity 	for (; i < test_insn_end - test_insn; ++i)
747d36db35SAvi Kivity 		test_insn[i] = 0x90; // nop
757d36db35SAvi Kivity 
767d36db35SAvi Kivity 	save = *inregs;
777d36db35SAvi Kivity 	asm volatile(
787d36db35SAvi Kivity 		"lgdtl %[gdt_descr] \n\t"
797d36db35SAvi Kivity 		"mov %%cr0, %[tmp] \n\t"
807d36db35SAvi Kivity 		"or $1, %[tmp] \n\t"
817d36db35SAvi Kivity 		"mov %[tmp], %%cr0 \n\t"
827d36db35SAvi Kivity 		"mov %[bigseg], %%gs \n\t"
837d36db35SAvi Kivity 		"and $-2, %[tmp] \n\t"
847d36db35SAvi Kivity 		"mov %[tmp], %%cr0 \n\t"
857d36db35SAvi Kivity 
8632001692SAvi Kivity                 "pushw %[save]+36; popfw \n\t"
877d36db35SAvi Kivity 		"xchg %%eax, %[save]+0 \n\t"
887d36db35SAvi Kivity 		"xchg %%ebx, %[save]+4 \n\t"
897d36db35SAvi Kivity 		"xchg %%ecx, %[save]+8 \n\t"
907d36db35SAvi Kivity 		"xchg %%edx, %[save]+12 \n\t"
917d36db35SAvi Kivity 		"xchg %%esi, %[save]+16 \n\t"
927d36db35SAvi Kivity 		"xchg %%edi, %[save]+20 \n\t"
937d36db35SAvi Kivity 		"xchg %%esp, %[save]+24 \n\t"
947d36db35SAvi Kivity 		"xchg %%ebp, %[save]+28 \n\t"
957d36db35SAvi Kivity 
967d36db35SAvi Kivity 		"test_insn: . = . + 32\n\t"
977d36db35SAvi Kivity 		"test_insn_end: \n\t"
987d36db35SAvi Kivity 
997d36db35SAvi Kivity 		"xchg %%eax, %[save]+0 \n\t"
1007d36db35SAvi Kivity 		"xchg %%ebx, %[save]+4 \n\t"
1017d36db35SAvi Kivity 		"xchg %%ecx, %[save]+8 \n\t"
1027d36db35SAvi Kivity 		"xchg %%edx, %[save]+12 \n\t"
1037d36db35SAvi Kivity 		"xchg %%esi, %[save]+16 \n\t"
1047d36db35SAvi Kivity 		"xchg %%edi, %[save]+20 \n\t"
1057d36db35SAvi Kivity 		"xchg %%esp, %[save]+24 \n\t"
1067d36db35SAvi Kivity 		"xchg %%ebp, %[save]+28 \n\t"
1077d36db35SAvi Kivity 
1087d36db35SAvi Kivity 		/* Save EFLAGS in outregs*/
1097d36db35SAvi Kivity 		"pushfl \n\t"
1107d36db35SAvi Kivity 		"popl %[save]+36 \n\t"
1117d36db35SAvi Kivity 
1127d36db35SAvi Kivity 		"xor %[tmp], %[tmp] \n\t"
1137d36db35SAvi Kivity 		"mov %[tmp], %%gs \n\t"
1147d36db35SAvi Kivity 		: [tmp]"=&r"(tmp), [save]"+m"(save)
1157d36db35SAvi Kivity 		: [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16)
1167d36db35SAvi Kivity 		: "cc", "memory"
1177d36db35SAvi Kivity 		);
1187d36db35SAvi Kivity 	*outregs = save;
1197d36db35SAvi Kivity }
1207d36db35SAvi Kivity 
1217d36db35SAvi Kivity #define R_AX 1
1227d36db35SAvi Kivity #define R_BX 2
1237d36db35SAvi Kivity #define R_CX 4
1247d36db35SAvi Kivity #define R_DX 8
1257d36db35SAvi Kivity #define R_SI 16
1267d36db35SAvi Kivity #define R_DI 32
1277d36db35SAvi Kivity #define R_SP 64
1287d36db35SAvi Kivity #define R_BP 128
1297d36db35SAvi Kivity 
1307d36db35SAvi Kivity int regs_equal(const struct regs *r1, const struct regs *r2, int ignore)
1317d36db35SAvi Kivity {
1327d36db35SAvi Kivity 	const u32 *p1 = &r1->eax, *p2 = &r2->eax;  // yuck
1337d36db35SAvi Kivity 	int i;
1347d36db35SAvi Kivity 
1357d36db35SAvi Kivity 	for (i = 0; i < 8; ++i)
1367d36db35SAvi Kivity 		if (!(ignore & (1 << i)) && p1[i] != p2[i])
1377d36db35SAvi Kivity 			return 0;
1387d36db35SAvi Kivity 	return 1;
1397d36db35SAvi Kivity }
1407d36db35SAvi Kivity 
141*81050840SAvi Kivity static void report(const char *name, _Bool ok)
142*81050840SAvi Kivity {
143*81050840SAvi Kivity     print_serial(ok ? "PASS: " : "FAIL: ");
144*81050840SAvi Kivity     print_serial(name);
145*81050840SAvi Kivity     print_serial("\n");
146*81050840SAvi Kivity }
147*81050840SAvi Kivity 
1487d36db35SAvi Kivity #define MK_INSN(name, str)				\
1497d36db35SAvi Kivity     asm (						\
150d4dc402cSAvi Kivity 	 ".pushsection .data.insn  \n\t"		\
151d4dc402cSAvi Kivity 	 "insn_" #name ": \n\t"				\
152d4dc402cSAvi Kivity 	 ".word 1001f, 1002f - 1001f \n\t"		\
153d4dc402cSAvi Kivity 	 ".popsection \n\t"				\
154d4dc402cSAvi Kivity 	 ".pushsection .text.insn, \"ax\" \n\t"		\
155d4dc402cSAvi Kivity 	 "1001: \n\t"					\
156d4dc402cSAvi Kivity 	 "insn_code_" #name ": " str " \n\t"		\
157d4dc402cSAvi Kivity 	 "1002: \n\t"					\
158d4dc402cSAvi Kivity 	 ".popsection"					\
1597d36db35SAvi Kivity     );							\
160d4dc402cSAvi Kivity     extern struct insn_desc insn_##name;
1617d36db35SAvi Kivity 
1627d36db35SAvi Kivity void test_xchg(void)
1637d36db35SAvi Kivity {
1647d36db35SAvi Kivity 	struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}, outregs;
1657d36db35SAvi Kivity 
1667d36db35SAvi Kivity 	MK_INSN(xchg_test1, "xchg %eax,%eax\n\t");
1677d36db35SAvi Kivity 	MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t");
1687d36db35SAvi Kivity 	MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t");
1697d36db35SAvi Kivity 	MK_INSN(xchg_test4, "xchg %eax,%edx\n\t");
1707d36db35SAvi Kivity 	MK_INSN(xchg_test5, "xchg %eax,%esi\n\t");
1717d36db35SAvi Kivity 	MK_INSN(xchg_test6, "xchg %eax,%edi\n\t");
1727d36db35SAvi Kivity 	MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t");
1737d36db35SAvi Kivity 	MK_INSN(xchg_test8, "xchg %eax,%esp\n\t");
1747d36db35SAvi Kivity 
175d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xchg_test1);
176*81050840SAvi Kivity 	report("xchg 1", regs_equal(&inregs, &outregs, 0));
1777d36db35SAvi Kivity 
178d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xchg_test2);
179*81050840SAvi Kivity 	report("xchg 2",
180*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_BX)
181*81050840SAvi Kivity 	       && outregs.eax == inregs.ebx && outregs.ebx == inregs.eax);
1827d36db35SAvi Kivity 
183d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xchg_test3);
184*81050840SAvi Kivity 	report("xchg 3",
185*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX)
186*81050840SAvi Kivity 	       && outregs.eax == inregs.ecx && outregs.ecx == inregs.eax);
1877d36db35SAvi Kivity 
188d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xchg_test4);
189*81050840SAvi Kivity 	report("xchg 4",
190*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_DX)
191*81050840SAvi Kivity 	       && outregs.eax == inregs.edx && outregs.edx == inregs.eax);
1927d36db35SAvi Kivity 
193d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xchg_test5);
194*81050840SAvi Kivity 	report("xchg 5", regs_equal(&inregs, &outregs, R_AX | R_SI)
195*81050840SAvi Kivity 	       && outregs.eax == inregs.esi && outregs.esi == inregs.eax);
1967d36db35SAvi Kivity 
197d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xchg_test6);
198*81050840SAvi Kivity 	report("xchg 6", regs_equal(&inregs, &outregs, R_AX | R_DI)
199*81050840SAvi Kivity 	       && outregs.eax == inregs.edi && outregs.edi == inregs.eax);
2007d36db35SAvi Kivity 
201d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xchg_test7);
202*81050840SAvi Kivity 	report("xchg 7", regs_equal(&inregs, &outregs, R_AX | R_BP)
203*81050840SAvi Kivity 	       && outregs.eax == inregs.ebp && outregs.ebp == inregs.eax);
2047d36db35SAvi Kivity 
205d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xchg_test8);
206*81050840SAvi Kivity 	report("xchg 8", regs_equal(&inregs, &outregs, R_AX | R_SP)
207*81050840SAvi Kivity 	       && outregs.eax == inregs.esp && outregs.esp == inregs.eax);
2087d36db35SAvi Kivity }
2097d36db35SAvi Kivity 
2107d36db35SAvi Kivity void test_shld(void)
2117d36db35SAvi Kivity {
2127d36db35SAvi Kivity 	struct regs inregs = { .eax = 0xbe, .edx = 0xef000000 }, outregs;
2137d36db35SAvi Kivity 	MK_INSN(shld_test, "shld $8,%edx,%eax\n\t");
2147d36db35SAvi Kivity 
215d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_shld_test);
216*81050840SAvi Kivity 	report("shld", outregs.eax == 0xbeef);
2177d36db35SAvi Kivity }
2187d36db35SAvi Kivity 
2197d36db35SAvi Kivity void test_mov_imm(void)
2207d36db35SAvi Kivity {
2217d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
2227d36db35SAvi Kivity 	MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax");
2237d36db35SAvi Kivity 	MK_INSN(mov_r16_imm_1, "mov $1234, %ax");
2247d36db35SAvi Kivity 	MK_INSN(mov_r8_imm_1, "mov $0x12, %ah");
2257d36db35SAvi Kivity 	MK_INSN(mov_r8_imm_2, "mov $0x34, %al");
2267d36db35SAvi Kivity 	MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t");
2277d36db35SAvi Kivity 
228d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_mov_r16_imm_1);
229*81050840SAvi Kivity 	report("mov 1",
230*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 1234);
2317d36db35SAvi Kivity 
2327d36db35SAvi Kivity 	/* test mov $imm, %eax */
233d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_mov_r32_imm_1);
234*81050840SAvi Kivity 	report("mov 2",
235*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX)
236*81050840SAvi Kivity 	       && outregs.eax == 1234567890);
2377d36db35SAvi Kivity 
2387d36db35SAvi Kivity 	/* test mov $imm, %al/%ah */
239d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_mov_r8_imm_1);
240*81050840SAvi Kivity 	report("mov 3",
241*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0x1200);
2427d36db35SAvi Kivity 
243d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_mov_r8_imm_2);
244*81050840SAvi Kivity 	report("mov 4",
245*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0x34);
2467d36db35SAvi Kivity 
247d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_mov_r8_imm_3);
248*81050840SAvi Kivity 	report("mov 5",
249*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0x1234);
2507d36db35SAvi Kivity }
2517d36db35SAvi Kivity 
2527d36db35SAvi Kivity void test_sub_imm(void)
2537d36db35SAvi Kivity {
2547d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
2557d36db35SAvi Kivity 	MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t");
2567d36db35SAvi Kivity 	MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t");
2577d36db35SAvi Kivity 	MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t");
2587d36db35SAvi Kivity 	MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t");
2597d36db35SAvi Kivity 
260d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_sub_r16_imm_1);
261*81050840SAvi Kivity 	report("sub 1",
262*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 1224);
2637d36db35SAvi Kivity 
2647d36db35SAvi Kivity 	/* test mov $imm, %eax */
265d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_sub_r32_imm_1);
266*81050840SAvi Kivity 	report("sub 2",
267*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX)
268*81050840SAvi Kivity 	       && outregs.eax == 1234567880);
2697d36db35SAvi Kivity 
2707d36db35SAvi Kivity 	/* test mov $imm, %al/%ah */
271d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_sub_r8_imm_1);
272*81050840SAvi Kivity 	report("sub 3",
273*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0x0200);
2747d36db35SAvi Kivity 
275d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_sub_r8_imm_2);
276*81050840SAvi Kivity 	report("sub 4",
277*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0x24);
2787d36db35SAvi Kivity }
2797d36db35SAvi Kivity 
2807d36db35SAvi Kivity void test_xor_imm(void)
2817d36db35SAvi Kivity {
2827d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
2837d36db35SAvi Kivity 	MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t");
2847d36db35SAvi Kivity 	MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t");
2857d36db35SAvi Kivity 	MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t");
2867d36db35SAvi Kivity 	MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t");
2877d36db35SAvi Kivity 
288d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xor_r16_imm_1);
289*81050840SAvi Kivity 	report("xor 1",
290*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0);
2917d36db35SAvi Kivity 
2927d36db35SAvi Kivity 	/* test mov $imm, %eax */
293d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xor_r32_imm_1);
294*81050840SAvi Kivity 	report("xor 2",
295*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0);
2967d36db35SAvi Kivity 
2977d36db35SAvi Kivity 	/* test mov $imm, %al/%ah */
298d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xor_r8_imm_1);
299*81050840SAvi Kivity 	report("xor 3",
300*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0);
3017d36db35SAvi Kivity 
302d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_xor_r8_imm_2);
303*81050840SAvi Kivity 	report("xor 4",
304*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0);
3057d36db35SAvi Kivity }
3067d36db35SAvi Kivity 
3077d36db35SAvi Kivity void test_cmp_imm(void)
3087d36db35SAvi Kivity {
3097d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
3107d36db35SAvi Kivity 	MK_INSN(cmp_test1, "mov $0x34, %al\n\t"
3117d36db35SAvi Kivity 			   "cmp $0x34, %al\n\t");
3127d36db35SAvi Kivity 	MK_INSN(cmp_test2, "mov $0x34, %al\n\t"
3137d36db35SAvi Kivity 			   "cmp $0x39, %al\n\t");
3147d36db35SAvi Kivity 	MK_INSN(cmp_test3, "mov $0x34, %al\n\t"
3157d36db35SAvi Kivity 			   "cmp $0x24, %al\n\t");
3167d36db35SAvi Kivity 
3177d36db35SAvi Kivity 	/* test cmp imm8 with AL */
3187d36db35SAvi Kivity 	/* ZF: (bit 6) Zero Flag becomes 1 if an operation results
3197d36db35SAvi Kivity 	 * in a 0 writeback, or 0 register
3207d36db35SAvi Kivity 	 */
321d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cmp_test1);
322*81050840SAvi Kivity 	report("cmp 1", (outregs.eflags & (1<<6)) == (1<<6));
3237d36db35SAvi Kivity 
324d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cmp_test2);
325*81050840SAvi Kivity 	report("cmp 2", (outregs.eflags & (1<<6)) == 0);
3267d36db35SAvi Kivity 
327d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cmp_test3);
328*81050840SAvi Kivity 	report("cmp 3", (outregs.eflags & (1<<6)) == 0);
3297d36db35SAvi Kivity }
3307d36db35SAvi Kivity 
3317d36db35SAvi Kivity void test_add_imm(void)
3327d36db35SAvi Kivity {
3337d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
3347d36db35SAvi Kivity 	MK_INSN(add_test1, "mov $0x43211234, %eax \n\t"
3357d36db35SAvi Kivity 			   "add $0x12344321, %eax \n\t");
3367d36db35SAvi Kivity 	MK_INSN(add_test2, "mov $0x12, %eax \n\t"
3377d36db35SAvi Kivity 			   "add $0x21, %al\n\t");
3387d36db35SAvi Kivity 
339d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_add_test1);
340*81050840SAvi Kivity 	report("add 1", outregs.eax == 0x55555555);
3417d36db35SAvi Kivity 
342d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_add_test2);
343*81050840SAvi Kivity 	report("add 2", outregs.eax == 0x33);
3447d36db35SAvi Kivity }
3457d36db35SAvi Kivity 
3467d36db35SAvi Kivity void test_eflags_insn(void)
3477d36db35SAvi Kivity {
3487d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
3497d36db35SAvi Kivity 	MK_INSN(clc, "clc");
350b3261e48SMohammed Gamal 	MK_INSN(stc, "stc");
3517d36db35SAvi Kivity 	MK_INSN(cli, "cli");
3527d36db35SAvi Kivity 	MK_INSN(sti, "sti");
3537d36db35SAvi Kivity 	MK_INSN(cld, "cld");
3547d36db35SAvi Kivity 	MK_INSN(std, "std");
3557d36db35SAvi Kivity 
356d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_clc);
357*81050840SAvi Kivity 	report("clc", (outregs.eflags & 1) == 0);
3587d36db35SAvi Kivity 
359d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_stc);
360*81050840SAvi Kivity 	report("stc", (outregs.eflags & 1) == 1);
361b3261e48SMohammed Gamal 
362d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cli);
363*81050840SAvi Kivity 	report("cli", !(outregs.eflags & (1 << 9)));
3647d36db35SAvi Kivity 
365d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_sti);
366*81050840SAvi Kivity 	report("sti", outregs.eflags & (1 << 9));
3677d36db35SAvi Kivity 
368d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cld);
369*81050840SAvi Kivity 	report("cld", !(outregs.eflags & (1 << 10)));
3707d36db35SAvi Kivity 
371d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_std);
372*81050840SAvi Kivity 	report("std", (outregs.eflags & (1 << 10)));
3737d36db35SAvi Kivity }
3747d36db35SAvi Kivity 
3757d36db35SAvi Kivity void test_io(void)
3767d36db35SAvi Kivity {
3777d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
3787d36db35SAvi Kivity 	MK_INSN(io_test1, "mov $0xff, %al \n\t"
3797d36db35SAvi Kivity 		          "out %al, $0xe0 \n\t"
3807d36db35SAvi Kivity 		          "mov $0x00, %al \n\t"
3817d36db35SAvi Kivity 			  "in $0xe0, %al \n\t");
3827d36db35SAvi Kivity 	MK_INSN(io_test2, "mov $0xffff, %ax \n\t"
3837d36db35SAvi Kivity 			  "out %ax, $0xe0 \n\t"
3847d36db35SAvi Kivity 			  "mov $0x0000, %ax \n\t"
3857d36db35SAvi Kivity 			  "in $0xe0, %ax \n\t");
3867d36db35SAvi Kivity 	MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t"
3877d36db35SAvi Kivity 			  "out %eax, $0xe0 \n\t"
3887d36db35SAvi Kivity 			  "mov $0x000000, %eax \n\t"
3897d36db35SAvi Kivity 			  "in $0xe0, %eax \n\t");
3907d36db35SAvi Kivity 	MK_INSN(io_test4, "mov $0xe0, %dx \n\t"
3917d36db35SAvi Kivity 			  "mov $0xff, %al \n\t"
3927d36db35SAvi Kivity 			  "out %al, %dx \n\t"
3937d36db35SAvi Kivity 			  "mov $0x00, %al \n\t"
3947d36db35SAvi Kivity 			  "in %dx, %al \n\t");
3957d36db35SAvi Kivity 	MK_INSN(io_test5, "mov $0xe0, %dx \n\t"
3967d36db35SAvi Kivity 			  "mov $0xffff, %ax \n\t"
3977d36db35SAvi Kivity 			  "out %ax, %dx \n\t"
3987d36db35SAvi Kivity 			  "mov $0x0000, %ax \n\t"
3997d36db35SAvi Kivity 			  "in %dx, %ax \n\t");
4007d36db35SAvi Kivity 	MK_INSN(io_test6, "mov $0xe0, %dx \n\t"
4017d36db35SAvi Kivity 			  "mov $0xffffffff, %eax \n\t"
4027d36db35SAvi Kivity 			  "out %eax, %dx \n\t"
4037d36db35SAvi Kivity 			  "mov $0x00000000, %eax \n\t"
4047d36db35SAvi Kivity 			  "in %dx, %eax \n\t");
4057d36db35SAvi Kivity 
406d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_io_test1);
407*81050840SAvi Kivity 	report("pio 1",
408*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0xff);
4097d36db35SAvi Kivity 
410d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_io_test2);
411*81050840SAvi Kivity 	report("pio 2",
412*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0xffff);
4137d36db35SAvi Kivity 
414d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_io_test3);
415*81050840SAvi Kivity 	report("pio 3",
416*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX)
417*81050840SAvi Kivity 	       && outregs.eax == 0xffffffff);
4187d36db35SAvi Kivity 
419d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_io_test4);
420*81050840SAvi Kivity 	report("pio 4",
421*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX|R_DX) && outregs.eax == 0xff);
4227d36db35SAvi Kivity 
423d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_io_test5);
424*81050840SAvi Kivity 	report("pio 5",
425*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX|R_DX)
426*81050840SAvi Kivity 	       && outregs.eax == 0xffff);
4277d36db35SAvi Kivity 
428d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_io_test6);
429*81050840SAvi Kivity 	report("pio 6",
430*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX|R_DX)
431*81050840SAvi Kivity 	       && outregs.eax == 0xffffffff);
4327d36db35SAvi Kivity }
4337d36db35SAvi Kivity 
434c0b7268dSAvi Kivity asm ("retf: lretw");
435c0b7268dSAvi Kivity extern void retf();
436c0b7268dSAvi Kivity 
4377d36db35SAvi Kivity void test_call(void)
4387d36db35SAvi Kivity {
4397d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
4407d36db35SAvi Kivity 	u32 esp[16];
441c0b7268dSAvi Kivity 	u32 addr;
4427d36db35SAvi Kivity 
4437d36db35SAvi Kivity 	inregs.esp = (u32)esp;
4447d36db35SAvi Kivity 
4457d36db35SAvi Kivity 	MK_INSN(call1, "mov $test_function, %eax \n\t"
4467d36db35SAvi Kivity 		       "call *%eax\n\t");
4477d36db35SAvi Kivity 	MK_INSN(call_near1, "jmp 2f\n\t"
4487d36db35SAvi Kivity 			    "1: mov $0x1234, %eax\n\t"
4497d36db35SAvi Kivity 			    "ret\n\t"
4507d36db35SAvi Kivity 			    "2: call 1b\t");
4517d36db35SAvi Kivity 	MK_INSN(call_near2, "call 1f\n\t"
4527d36db35SAvi Kivity 			    "jmp 2f\n\t"
4537d36db35SAvi Kivity 			    "1: mov $0x1234, %eax\n\t"
4547d36db35SAvi Kivity 			    "ret\n\t"
4557d36db35SAvi Kivity 			    "2:\t");
456c0b7268dSAvi Kivity 	MK_INSN(call_far1,  "lcallw *(%ebx)\n\t");
457c6061817SAvi Kivity 	MK_INSN(ret_imm,    "sub $10, %sp; jmp 2f; 1: retw $10; 2: callw 1b");
4587d36db35SAvi Kivity 
459d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_call1);
460*81050840SAvi Kivity 	report("call 1",
461*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0x1234);
4627d36db35SAvi Kivity 
463d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_call_near1);
464*81050840SAvi Kivity 	report("call near 1",
465*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0x1234);
4667d36db35SAvi Kivity 
467d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_call_near2);
468*81050840SAvi Kivity 	report("call near 2",
469*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0x1234);
470c0b7268dSAvi Kivity 
471c0b7268dSAvi Kivity 	addr = (((unsigned)retf >> 4) << 16) | ((unsigned)retf & 0x0f);
472c0b7268dSAvi Kivity 	inregs.ebx = (unsigned)&addr;
473d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_call_far1);
474*81050840SAvi Kivity 	report("call far 1", regs_equal(&inregs, &outregs, 0));
475c6061817SAvi Kivity 
476d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_ret_imm);
477*81050840SAvi Kivity 	report("ret imm 1", regs_equal(&inregs, &outregs, 0));
4787d36db35SAvi Kivity }
4797d36db35SAvi Kivity 
4807d36db35SAvi Kivity void test_jcc_short(void)
4817d36db35SAvi Kivity {
4827d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
4837d36db35SAvi Kivity 	MK_INSN(jnz_short1, "jnz 1f\n\t"
4847d36db35SAvi Kivity 			    "mov $0x1234, %eax\n\t"
4857d36db35SAvi Kivity 		            "1:\n\t");
4867d36db35SAvi Kivity 	MK_INSN(jnz_short2, "1:\n\t"
4877d36db35SAvi Kivity 			    "cmp $0x1234, %eax\n\t"
4887d36db35SAvi Kivity 			    "mov $0x1234, %eax\n\t"
4897d36db35SAvi Kivity 		            "jnz 1b\n\t");
4907d36db35SAvi Kivity 	MK_INSN(jmp_short1, "jmp 1f\n\t"
4917d36db35SAvi Kivity 		      "mov $0x1234, %eax\n\t"
4927d36db35SAvi Kivity 		      "1:\n\t");
4937d36db35SAvi Kivity 
494d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_jnz_short1);
495*81050840SAvi Kivity 	report("jnz short 1", regs_equal(&inregs, &outregs, 0));
4967d36db35SAvi Kivity 
497d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_jnz_short2);
498*81050840SAvi Kivity 	report("jnz short 2",
499*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX)
500*81050840SAvi Kivity 	       && (outregs.eflags & (1 << 6)));
5017d36db35SAvi Kivity 
502d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_jmp_short1);
503*81050840SAvi Kivity 	report("jmp short 1", regs_equal(&inregs, &outregs, 0));
5047d36db35SAvi Kivity }
5057d36db35SAvi Kivity 
5067d36db35SAvi Kivity void test_jcc_near(void)
5077d36db35SAvi Kivity {
5087d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
5097d36db35SAvi Kivity 	/* encode near jmp manually. gas will not do it if offsets < 127 byte */
5107d36db35SAvi Kivity 	MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t"
5117d36db35SAvi Kivity 		           "mov $0x1234, %eax\n\t");
5127d36db35SAvi Kivity 	MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t"
5137d36db35SAvi Kivity 			   "mov $0x1234, %eax\n\t"
5147d36db35SAvi Kivity 		           ".byte 0x0f, 0x85, 0xf0, 0xff\n\t");
5157d36db35SAvi Kivity 	MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t"
5167d36db35SAvi Kivity 		           "mov $0x1234, %eax\n\t");
5177d36db35SAvi Kivity 
518d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_jnz_near1);
519*81050840SAvi Kivity 	report("jnz near 1", regs_equal(&inregs, &outregs, 0));
5207d36db35SAvi Kivity 
521d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_jnz_near2);
522*81050840SAvi Kivity 	report("jnz near 2",
523*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX)
524*81050840SAvi Kivity 	       && (outregs.eflags & (1 << 6)));
5257d36db35SAvi Kivity 
526d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_jmp_near1);
527*81050840SAvi Kivity 	report("jmp near 1", regs_equal(&inregs, &outregs, 0));
5287d36db35SAvi Kivity }
5297d36db35SAvi Kivity 
5307d36db35SAvi Kivity void test_long_jmp()
5317d36db35SAvi Kivity {
5327d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
5337d36db35SAvi Kivity 	u32 esp[16];
5347d36db35SAvi Kivity 
5357d36db35SAvi Kivity 	inregs.esp = (u32)esp;
5367d36db35SAvi Kivity 	MK_INSN(long_jmp, "call 1f\n\t"
5377d36db35SAvi Kivity 			  "jmp 2f\n\t"
5387d36db35SAvi Kivity 			  "1: jmp $0, $test_function\n\t"
5397d36db35SAvi Kivity 		          "2:\n\t");
540d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_long_jmp);
541*81050840SAvi Kivity 	report("jmp far 1",
542*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 0x1234);
5437d36db35SAvi Kivity }
544fa74f8a6SMohammed Gamal 
5457d36db35SAvi Kivity void test_push_pop()
5467d36db35SAvi Kivity {
5477d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
5487d36db35SAvi Kivity 	MK_INSN(push32, "mov $0x12345678, %eax\n\t"
5497d36db35SAvi Kivity 			"push %eax\n\t"
5507d36db35SAvi Kivity 			"pop %ebx\n\t");
5517d36db35SAvi Kivity 	MK_INSN(push16, "mov $0x1234, %ax\n\t"
5527d36db35SAvi Kivity 			"push %ax\n\t"
5537d36db35SAvi Kivity 			"pop %bx\n\t");
5547d36db35SAvi Kivity 
5557d36db35SAvi Kivity 	MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten
5567d36db35SAvi Kivity 			 "mov $0x123, %ax\n\t"
5577d36db35SAvi Kivity 			 "mov %ax, %es\n\t"
5587d36db35SAvi Kivity 			 "push %es\n\t"
5597d36db35SAvi Kivity 			 "pop %bx \n\t"
5607d36db35SAvi Kivity 			 );
5617d36db35SAvi Kivity 	MK_INSN(pop_es, "push %ax\n\t"
5627d36db35SAvi Kivity 			"pop %es\n\t"
5637d36db35SAvi Kivity 			"mov %es, %bx\n\t"
5647d36db35SAvi Kivity 			);
5657d36db35SAvi Kivity 	MK_INSN(push_pop_ss, "push %ss\n\t"
5667d36db35SAvi Kivity 			     "pushw %ax\n\t"
5677d36db35SAvi Kivity 			     "popw %ss\n\t"
5687d36db35SAvi Kivity 			     "mov %ss, %bx\n\t"
5697d36db35SAvi Kivity 			     "pop %ss\n\t"
5707d36db35SAvi Kivity 			);
5717d36db35SAvi Kivity 	MK_INSN(push_pop_fs, "push %fs\n\t"
5727d36db35SAvi Kivity 			     "pushl %eax\n\t"
5737d36db35SAvi Kivity 			     "popl %fs\n\t"
5747d36db35SAvi Kivity 			     "mov %fs, %ebx\n\t"
5757d36db35SAvi Kivity 			     "pop %fs\n\t"
5767d36db35SAvi Kivity 			);
5777d36db35SAvi Kivity 
578d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_push32);
579*81050840SAvi Kivity 	report("push/pop 1",
580*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX|R_BX)
581*81050840SAvi Kivity 	       && outregs.eax == outregs.ebx && outregs.eax == 0x12345678);
5827d36db35SAvi Kivity 
583d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_push16);
584*81050840SAvi Kivity 	report("push/pop 2",
585*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX|R_BX)
586*81050840SAvi Kivity 	       && outregs.eax == outregs.ebx && outregs.eax == 0x1234);
5877d36db35SAvi Kivity 
588d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_push_es);
589*81050840SAvi Kivity 	report("push/pop 3",
590*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX|R_BX)
591*81050840SAvi Kivity 	       && outregs.ebx == outregs.eax && outregs.eax == 0x123);
5927d36db35SAvi Kivity 
593d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_pop_es);
594*81050840SAvi Kivity 	report("push/pop 4",
595*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX|R_BX)
596*81050840SAvi Kivity 	       &&  outregs.ebx == outregs.eax);
5977d36db35SAvi Kivity 
598d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_push_pop_ss);
599*81050840SAvi Kivity 	report("push/pop 5",
600*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX|R_BX)
601*81050840SAvi Kivity 	       && outregs.ebx == outregs.eax);
6027d36db35SAvi Kivity 
603d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_push_pop_fs);
604*81050840SAvi Kivity 	report("push/pop 6",
605*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX|R_BX)
606*81050840SAvi Kivity 	       && outregs.ebx == outregs.eax);
6077d36db35SAvi Kivity }
6087d36db35SAvi Kivity 
6097d36db35SAvi Kivity void test_null(void)
6107d36db35SAvi Kivity {
6117d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
612d4dc402cSAvi Kivity 	MK_INSN(null, "");
613d4dc402cSAvi Kivity 
614d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_null);
615*81050840SAvi Kivity 	report("null", regs_equal(&inregs, &outregs, 0));
6167d36db35SAvi Kivity }
6177d36db35SAvi Kivity 
6187d36db35SAvi Kivity struct {
6197d36db35SAvi Kivity     char stack[500];
6207d36db35SAvi Kivity     char top[];
6217d36db35SAvi Kivity } tmp_stack;
6227d36db35SAvi Kivity 
6237d36db35SAvi Kivity void test_pusha_popa()
6247d36db35SAvi Kivity {
6257d36db35SAvi Kivity 	struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = (unsigned long)&tmp_stack.top }, outregs;
6267d36db35SAvi Kivity 
6277d36db35SAvi Kivity 	MK_INSN(pusha, "pusha\n\t"
6287d36db35SAvi Kivity 		       "pop %edi\n\t"
6297d36db35SAvi Kivity 		       "pop %esi\n\t"
6307d36db35SAvi Kivity 		       "pop %ebp\n\t"
6317d36db35SAvi Kivity 		       "add $4, %esp\n\t"
6327d36db35SAvi Kivity 		       "pop %ebx\n\t"
6337d36db35SAvi Kivity 		       "pop %edx\n\t"
6347d36db35SAvi Kivity 		       "pop %ecx\n\t"
6357d36db35SAvi Kivity 		       "pop %eax\n\t"
6367d36db35SAvi Kivity 		       );
6377d36db35SAvi Kivity 
6387d36db35SAvi Kivity 	MK_INSN(popa, "push %eax\n\t"
6397d36db35SAvi Kivity 		      "push %ecx\n\t"
6407d36db35SAvi Kivity 		      "push %edx\n\t"
6417d36db35SAvi Kivity 		      "push %ebx\n\t"
6427d36db35SAvi Kivity 		      "push %esp\n\t"
6437d36db35SAvi Kivity 		      "push %ebp\n\t"
6447d36db35SAvi Kivity 		      "push %esi\n\t"
6457d36db35SAvi Kivity 		      "push %edi\n\t"
6467d36db35SAvi Kivity 		      "popa\n\t"
6477d36db35SAvi Kivity 		      );
6487d36db35SAvi Kivity 
649d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_pusha);
650*81050840SAvi Kivity 	report("pusha/popa 1", regs_equal(&inregs, &outregs, 0));
6517d36db35SAvi Kivity 
652d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_popa);
653*81050840SAvi Kivity 	report("pusha/popa 1", regs_equal(&inregs, &outregs, 0));
6547d36db35SAvi Kivity }
6557d36db35SAvi Kivity 
6567d36db35SAvi Kivity void test_iret()
6577d36db35SAvi Kivity {
6587d36db35SAvi Kivity 	struct regs inregs = { 0 }, outregs;
6597d36db35SAvi Kivity 
6607d36db35SAvi Kivity 	MK_INSN(iret32, "pushf\n\t"
6617d36db35SAvi Kivity 			"pushl %cs\n\t"
6627d36db35SAvi Kivity 			"call 1f\n\t" /* a near call will push eip onto the stack */
6637d36db35SAvi Kivity 			"jmp 2f\n\t"
6647d36db35SAvi Kivity 			"1: iret\n\t"
6657d36db35SAvi Kivity 			"2:\n\t"
6667d36db35SAvi Kivity 		     );
6677d36db35SAvi Kivity 
6687d36db35SAvi Kivity 	MK_INSN(iret16, "pushfw\n\t"
6697d36db35SAvi Kivity 			"pushw %cs\n\t"
6707d36db35SAvi Kivity 			"callw 1f\n\t"
6717d36db35SAvi Kivity 			"jmp 2f\n\t"
6727d36db35SAvi Kivity 			"1: iretw\n\t"
6737d36db35SAvi Kivity 			"2:\n\t");
6747d36db35SAvi Kivity 
6757d36db35SAvi Kivity 	MK_INSN(iret_flags32, "pushfl\n\t"
6767d36db35SAvi Kivity 			      "popl %eax\n\t"
6777d36db35SAvi Kivity 			      "andl $~0x2, %eax\n\t"
6787d36db35SAvi Kivity 			      "orl $0xffc08028, %eax\n\t"
6797d36db35SAvi Kivity 			      "pushl %eax\n\t"
6807d36db35SAvi Kivity 			      "pushl %cs\n\t"
6817d36db35SAvi Kivity 			      "call 1f\n\t"
6827d36db35SAvi Kivity 			      "jmp 2f\n\t"
6837d36db35SAvi Kivity 			      "1: iret\n\t"
6847d36db35SAvi Kivity 			      "2:\n\t");
6857d36db35SAvi Kivity 
6867d36db35SAvi Kivity 	MK_INSN(iret_flags16, "pushfw\n\t"
6877d36db35SAvi Kivity 			      "popw %ax\n\t"
6887d36db35SAvi Kivity 			      "and $~0x2, %ax\n\t"
6897d36db35SAvi Kivity 			      "or $0x8028, %ax\n\t"
6907d36db35SAvi Kivity 			      "pushw %ax\n\t"
6917d36db35SAvi Kivity 			      "pushw %cs\n\t"
6927d36db35SAvi Kivity 			      "callw 1f\n\t"
6937d36db35SAvi Kivity 			      "jmp 2f\n\t"
6947d36db35SAvi Kivity 			      "1: iretw\n\t"
6957d36db35SAvi Kivity 			      "2:\n\t");
6967d36db35SAvi Kivity 
697d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_iret32);
698*81050840SAvi Kivity 	report("iret 1", regs_equal(&inregs, &outregs, 0));
6997d36db35SAvi Kivity 
700d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_iret16);
701*81050840SAvi Kivity 	report("iret 2", regs_equal(&inregs, &outregs, 0));
7027d36db35SAvi Kivity 
703d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_iret_flags32);
704*81050840SAvi Kivity 	report("iret 3", regs_equal(&inregs, &outregs, R_AX));
7057d36db35SAvi Kivity 
706d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_iret_flags16);
707*81050840SAvi Kivity 	report("iret 4", regs_equal(&inregs, &outregs, R_AX));
7087d36db35SAvi Kivity }
7097d36db35SAvi Kivity 
71096b9ca1eSMohammed Gamal void test_int()
71196b9ca1eSMohammed Gamal {
71296b9ca1eSMohammed Gamal 	struct regs inregs = { 0 }, outregs;
71396b9ca1eSMohammed Gamal 
71496b9ca1eSMohammed Gamal 	*(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */
71596b9ca1eSMohammed Gamal 	*(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */
71696b9ca1eSMohammed Gamal 
71796b9ca1eSMohammed Gamal 	MK_INSN(int11, "int $0x11\n\t");
71896b9ca1eSMohammed Gamal 
719d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_int11);
720*81050840SAvi Kivity 	report("int 1", regs_equal(&inregs, &outregs, 0));
72196b9ca1eSMohammed Gamal }
72296b9ca1eSMohammed Gamal 
723fa74f8a6SMohammed Gamal void test_imul()
724fa74f8a6SMohammed Gamal {
725fa74f8a6SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
726fa74f8a6SMohammed Gamal 
727fa74f8a6SMohammed Gamal 	MK_INSN(imul8_1, "mov $2, %al\n\t"
728fa74f8a6SMohammed Gamal 			"mov $-4, %cx\n\t"
729fa74f8a6SMohammed Gamal 			"imul %cl\n\t");
730fa74f8a6SMohammed Gamal 
731fa74f8a6SMohammed Gamal 	MK_INSN(imul16_1, "mov $2, %ax\n\t"
732fa74f8a6SMohammed Gamal 		      "mov $-4, %cx\n\t"
733fa74f8a6SMohammed Gamal 		      "imul %cx\n\t");
734fa74f8a6SMohammed Gamal 
735fa74f8a6SMohammed Gamal 	MK_INSN(imul32_1, "mov $2, %eax\n\t"
736fa74f8a6SMohammed Gamal 		       "mov $-4, %ecx\n\t"
737fa74f8a6SMohammed Gamal 		       "imul %ecx\n\t");
738fa74f8a6SMohammed Gamal 
739fa74f8a6SMohammed Gamal 	MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t"
740fa74f8a6SMohammed Gamal 			"mov $4, %cx\n\t"
741fa74f8a6SMohammed Gamal 			"imul %cl\n\t");
742fa74f8a6SMohammed Gamal 
743fa74f8a6SMohammed Gamal 	MK_INSN(imul16_2, "mov $2, %ax\n\t"
744fa74f8a6SMohammed Gamal 			"mov $4, %cx\n\t"
745fa74f8a6SMohammed Gamal 			"imul %cx\n\t");
746fa74f8a6SMohammed Gamal 
747fa74f8a6SMohammed Gamal 	MK_INSN(imul32_2, "mov $2, %eax\n\t"
748fa74f8a6SMohammed Gamal 			"mov $4, %ecx\n\t"
749fa74f8a6SMohammed Gamal 			"imul %ecx\n\t");
750fa74f8a6SMohammed Gamal 
751d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_imul8_1);
752*81050840SAvi Kivity 	report("imul 1",
753*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
754*81050840SAvi Kivity 	       && (outregs.eax & 0xff) == (u8)-8);
755fa74f8a6SMohammed Gamal 
756d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_imul16_1);
757*81050840SAvi Kivity 	report("imul 2",
758*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
759*81050840SAvi Kivity 	       && outregs.eax == (u16)-8);
760fa74f8a6SMohammed Gamal 
761d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_imul32_1);
762*81050840SAvi Kivity 	report("imul 3",
763*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
764*81050840SAvi Kivity 	       && outregs.eax == (u32)-8);
765fa74f8a6SMohammed Gamal 
766d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_imul8_2);
767*81050840SAvi Kivity 	report("imul 4",
768*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
769*81050840SAvi Kivity 	       && (outregs.eax & 0xffff) == 8
770*81050840SAvi Kivity 	       && (outregs.eax & 0xffff0000) == 0x12340000);
771fa74f8a6SMohammed Gamal 
772d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_imul16_2);
773*81050840SAvi Kivity 	report("imul 5",
774*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
775*81050840SAvi Kivity 	       && outregs.eax == 8);
776fa74f8a6SMohammed Gamal 
777d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_imul32_2);
778*81050840SAvi Kivity 	report("imul 6",
779*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
780*81050840SAvi Kivity 	       && outregs.eax == 8);
781fa74f8a6SMohammed Gamal }
782fa74f8a6SMohammed Gamal 
78359317bd1SMohammed Gamal void test_mul()
78459317bd1SMohammed Gamal {
78559317bd1SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
78659317bd1SMohammed Gamal 
78759317bd1SMohammed Gamal 	MK_INSN(mul8, "mov $2, %al\n\t"
78859317bd1SMohammed Gamal 			"mov $4, %cx\n\t"
78959317bd1SMohammed Gamal 			"imul %cl\n\t");
79059317bd1SMohammed Gamal 
79159317bd1SMohammed Gamal 	MK_INSN(mul16, "mov $2, %ax\n\t"
79259317bd1SMohammed Gamal 			"mov $4, %cx\n\t"
79359317bd1SMohammed Gamal 			"imul %cx\n\t");
79459317bd1SMohammed Gamal 
79559317bd1SMohammed Gamal 	MK_INSN(mul32, "mov $2, %eax\n\t"
79659317bd1SMohammed Gamal 			"mov $4, %ecx\n\t"
79759317bd1SMohammed Gamal 			"imul %ecx\n\t");
79859317bd1SMohammed Gamal 
799d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_mul8);
800*81050840SAvi Kivity 	report("mul 1",
801*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
802*81050840SAvi Kivity 	       && (outregs.eax & 0xff) == 8);
80359317bd1SMohammed Gamal 
804d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_mul16);
805*81050840SAvi Kivity 	report("mul 2",
806*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
807*81050840SAvi Kivity 	       && outregs.eax == 8);
80859317bd1SMohammed Gamal 
809d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_mul32);
810*81050840SAvi Kivity 	report("mul 3",
811*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
812*81050840SAvi Kivity 	       && outregs.eax == 8);
81359317bd1SMohammed Gamal }
81459317bd1SMohammed Gamal 
8150d4c7614SMohammed Gamal void test_div()
8160d4c7614SMohammed Gamal {
8170d4c7614SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
8180d4c7614SMohammed Gamal 
8190d4c7614SMohammed Gamal 	MK_INSN(div8, "mov $257, %ax\n\t"
8200d4c7614SMohammed Gamal 			"mov $2, %cl\n\t"
8210d4c7614SMohammed Gamal 			"div %cl\n\t");
8220d4c7614SMohammed Gamal 
8230d4c7614SMohammed Gamal 	MK_INSN(div16, "mov $512, %ax\n\t"
8240d4c7614SMohammed Gamal 			"mov $5, %cx\n\t"
8250d4c7614SMohammed Gamal 			"div %cx\n\t");
8260d4c7614SMohammed Gamal 
8270d4c7614SMohammed Gamal 	MK_INSN(div32, "mov $512, %eax\n\t"
8280d4c7614SMohammed Gamal 			"mov $5, %ecx\n\t"
8290d4c7614SMohammed Gamal 			"div %ecx\n\t");
8300d4c7614SMohammed Gamal 
831d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_div8);
832*81050840SAvi Kivity 	report("div 1",
833*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
834*81050840SAvi Kivity 	       && outregs.eax == 384);
8350d4c7614SMohammed Gamal 
836d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_div16);
837*81050840SAvi Kivity 	report("div 2",
838*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
839*81050840SAvi Kivity 	       && outregs.eax == 102 && outregs.edx == 2);
8400d4c7614SMohammed Gamal 
841d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_div32);
842*81050840SAvi Kivity 	report("div 3",
843*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
844*81050840SAvi Kivity 	       && outregs.eax == 102 && outregs.edx == 2);
8450d4c7614SMohammed Gamal }
8460d4c7614SMohammed Gamal 
8470d4c7614SMohammed Gamal void test_idiv()
8480d4c7614SMohammed Gamal {
8490d4c7614SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
8500d4c7614SMohammed Gamal 
8510d4c7614SMohammed Gamal 	MK_INSN(idiv8, "mov $256, %ax\n\t"
8520d4c7614SMohammed Gamal 			"mov $-2, %cl\n\t"
8530d4c7614SMohammed Gamal 			"idiv %cl\n\t");
8540d4c7614SMohammed Gamal 
8550d4c7614SMohammed Gamal 	MK_INSN(idiv16, "mov $512, %ax\n\t"
8560d4c7614SMohammed Gamal 			"mov $-2, %cx\n\t"
8570d4c7614SMohammed Gamal 			"idiv %cx\n\t");
8580d4c7614SMohammed Gamal 
8590d4c7614SMohammed Gamal 	MK_INSN(idiv32, "mov $512, %eax\n\t"
8600d4c7614SMohammed Gamal 			"mov $-2, %ecx\n\t"
8610d4c7614SMohammed Gamal 			"idiv %ecx\n\t");
8620d4c7614SMohammed Gamal 
863d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_idiv8);
864*81050840SAvi Kivity 	report("idiv 1",
865*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
866*81050840SAvi Kivity 	       && outregs.eax == (u8)-128);
8670d4c7614SMohammed Gamal 
868d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_idiv16);
869*81050840SAvi Kivity 	report("idiv 2",
870*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
871*81050840SAvi Kivity 	       && outregs.eax == (u16)-256);
8720d4c7614SMohammed Gamal 
873d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_idiv32);
874*81050840SAvi Kivity 	report("idiv 3",
875*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX)
876*81050840SAvi Kivity 	       && outregs.eax == (u32)-256);
8770d4c7614SMohammed Gamal }
8780d4c7614SMohammed Gamal 
8796e293cf5SWei Yongjun void test_cbw(void)
8806e293cf5SWei Yongjun {
8816e293cf5SWei Yongjun 	struct regs inregs = { 0 }, outregs;
8826e293cf5SWei Yongjun 
8836e293cf5SWei Yongjun 	MK_INSN(cbw, "mov $0xFE, %eax \n\t"
8846e293cf5SWei Yongjun 		     "cbw\n\t");
8856e293cf5SWei Yongjun 	MK_INSN(cwde, "mov $0xFFFE, %eax \n\t"
8866e293cf5SWei Yongjun 		      "cwde\n\t");
8876e293cf5SWei Yongjun 
888d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cbw);
889*81050840SAvi Kivity 	report("cbq 1", outregs.eax == 0xFFFE);
8906e293cf5SWei Yongjun 
891d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cwde);
892*81050840SAvi Kivity 	report("cwde 1", outregs.eax == 0xFFFFFFFE);
8936e293cf5SWei Yongjun }
8946e293cf5SWei Yongjun 
895eacef4e2SWei Yongjun void test_loopcc(void)
896eacef4e2SWei Yongjun {
897eacef4e2SWei Yongjun 	struct regs inregs = { 0 }, outregs;
898eacef4e2SWei Yongjun 
899eacef4e2SWei Yongjun 	MK_INSN(loop, "mov $10, %ecx\n\t"
900eacef4e2SWei Yongjun 		      "1: inc %eax\n\t"
901eacef4e2SWei Yongjun 		      "loop 1b\n\t");
902eacef4e2SWei Yongjun 
903eacef4e2SWei Yongjun 	MK_INSN(loope, "mov $10, %ecx\n\t"
904eacef4e2SWei Yongjun 		       "mov $1, %eax\n\t"
905eacef4e2SWei Yongjun 		       "1: dec %eax\n\t"
906eacef4e2SWei Yongjun 		       "loope 1b\n\t");
907eacef4e2SWei Yongjun 
908eacef4e2SWei Yongjun 	MK_INSN(loopne, "mov $10, %ecx\n\t"
909eacef4e2SWei Yongjun 		        "mov $5, %eax\n\t"
910eacef4e2SWei Yongjun 		        "1: dec %eax\n\t"
911eacef4e2SWei Yongjun 			"loopne 1b\n\t");
912eacef4e2SWei Yongjun 
913d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_loop);
914*81050840SAvi Kivity 	report("LOOPcc short 1",
915*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX) && outregs.eax == 10);
916eacef4e2SWei Yongjun 
917d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_loope);
918*81050840SAvi Kivity 	report("LOOPcc short 2",
919*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX)
920*81050840SAvi Kivity 	       && outregs.eax == -1 && outregs.ecx == 8);
921eacef4e2SWei Yongjun 
922d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_loopne);
923*81050840SAvi Kivity 	report("LOOPcc short 3",
924*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_CX)
925*81050840SAvi Kivity 	       && outregs.eax == 0 && outregs.ecx == 5);
926eacef4e2SWei Yongjun }
927eacef4e2SWei Yongjun 
928b274feedSAvi Kivity static void test_das(void)
929b274feedSAvi Kivity {
930b274feedSAvi Kivity     struct regs inregs = { 0 }, outregs = { 0 };
931b274feedSAvi Kivity     short i;
932*81050840SAvi Kivity     u16 nr_fail = 0;
933b274feedSAvi Kivity     static unsigned test_cases[1024] = {
934b274feedSAvi Kivity         0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00,
935b274feedSAvi Kivity         0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01,
936b274feedSAvi Kivity         0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02,
937b274feedSAvi Kivity         0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03,
938b274feedSAvi Kivity         0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04,
939b274feedSAvi Kivity         0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05,
940b274feedSAvi Kivity         0x06000606, 0x8701a606, 0x56100006, 0x9711a006,
941b274feedSAvi Kivity         0x02000707, 0x8301a707, 0x12100107, 0x9311a107,
942b274feedSAvi Kivity         0x02000808, 0x8301a808, 0x12100208, 0x9311a208,
943b274feedSAvi Kivity         0x06000909, 0x8701a909, 0x16100309, 0x9711a309,
944b274feedSAvi Kivity         0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a,
945b274feedSAvi Kivity         0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b,
946b274feedSAvi Kivity         0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c,
947b274feedSAvi Kivity         0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d,
948b274feedSAvi Kivity         0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e,
949b274feedSAvi Kivity         0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f,
950b274feedSAvi Kivity         0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10,
951b274feedSAvi Kivity         0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11,
952b274feedSAvi Kivity         0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12,
953b274feedSAvi Kivity         0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13,
954b274feedSAvi Kivity         0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14,
955b274feedSAvi Kivity         0x02001515, 0x8301b515, 0x16100f15, 0x9711af15,
956b274feedSAvi Kivity         0x02001616, 0x8301b616, 0x12101016, 0x9311b016,
957b274feedSAvi Kivity         0x06001717, 0x8701b717, 0x16101117, 0x9711b117,
958b274feedSAvi Kivity         0x06001818, 0x8701b818, 0x16101218, 0x9711b218,
959b274feedSAvi Kivity         0x02001919, 0x8301b919, 0x12101319, 0x9311b319,
960b274feedSAvi Kivity         0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a,
961b274feedSAvi Kivity         0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b,
962b274feedSAvi Kivity         0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c,
963b274feedSAvi Kivity         0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d,
964b274feedSAvi Kivity         0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e,
965b274feedSAvi Kivity         0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f,
966b274feedSAvi Kivity         0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20,
967b274feedSAvi Kivity         0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21,
968b274feedSAvi Kivity         0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22,
969b274feedSAvi Kivity         0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23,
970b274feedSAvi Kivity         0x06002424, 0x8301c424, 0x16101e24, 0x9711be24,
971b274feedSAvi Kivity         0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25,
972b274feedSAvi Kivity         0x02002626, 0x8701c626, 0x12102026, 0x9711c026,
973b274feedSAvi Kivity         0x06002727, 0x8301c727, 0x16102127, 0x9311c127,
974b274feedSAvi Kivity         0x06002828, 0x8301c828, 0x16102228, 0x9311c228,
975b274feedSAvi Kivity         0x02002929, 0x8701c929, 0x12102329, 0x9711c329,
976b274feedSAvi Kivity         0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a,
977b274feedSAvi Kivity         0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b,
978b274feedSAvi Kivity         0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c,
979b274feedSAvi Kivity         0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d,
980b274feedSAvi Kivity         0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e,
981b274feedSAvi Kivity         0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f,
982b274feedSAvi Kivity         0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30,
983b274feedSAvi Kivity         0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31,
984b274feedSAvi Kivity         0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32,
985b274feedSAvi Kivity         0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33,
986b274feedSAvi Kivity         0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34,
987b274feedSAvi Kivity         0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35,
988b274feedSAvi Kivity         0x06003636, 0x8301d636, 0x16103036, 0x9311d036,
989b274feedSAvi Kivity         0x02003737, 0x8701d737, 0x12103137, 0x9711d137,
990b274feedSAvi Kivity         0x02003838, 0x8701d838, 0x12103238, 0x9711d238,
991b274feedSAvi Kivity         0x06003939, 0x8301d939, 0x16103339, 0x9311d339,
992b274feedSAvi Kivity         0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a,
993b274feedSAvi Kivity         0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b,
994b274feedSAvi Kivity         0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c,
995b274feedSAvi Kivity         0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d,
996b274feedSAvi Kivity         0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e,
997b274feedSAvi Kivity         0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f,
998b274feedSAvi Kivity         0x02004040, 0x8301e040, 0x16103a40, 0x9311da40,
999b274feedSAvi Kivity         0x06004141, 0x8701e141, 0x12103b41, 0x9711db41,
1000b274feedSAvi Kivity         0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42,
1001b274feedSAvi Kivity         0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43,
1002b274feedSAvi Kivity         0x06004444, 0x8701e444, 0x12103e44, 0x9711de44,
1003b274feedSAvi Kivity         0x02004545, 0x8301e545, 0x16103f45, 0x9311df45,
1004b274feedSAvi Kivity         0x02004646, 0x8301e646, 0x12104046, 0x9311e046,
1005b274feedSAvi Kivity         0x06004747, 0x8701e747, 0x16104147, 0x9711e147,
1006b274feedSAvi Kivity         0x06004848, 0x8701e848, 0x16104248, 0x9711e248,
1007b274feedSAvi Kivity         0x02004949, 0x8301e949, 0x12104349, 0x9311e349,
1008b274feedSAvi Kivity         0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a,
1009b274feedSAvi Kivity         0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b,
1010b274feedSAvi Kivity         0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c,
1011b274feedSAvi Kivity         0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d,
1012b274feedSAvi Kivity         0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e,
1013b274feedSAvi Kivity         0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f,
1014b274feedSAvi Kivity         0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50,
1015b274feedSAvi Kivity         0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51,
1016b274feedSAvi Kivity         0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52,
1017b274feedSAvi Kivity         0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53,
1018b274feedSAvi Kivity         0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54,
1019b274feedSAvi Kivity         0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55,
1020b274feedSAvi Kivity         0x06005656, 0x8701f656, 0x16105056, 0x9711f056,
1021b274feedSAvi Kivity         0x02005757, 0x8301f757, 0x12105157, 0x9311f157,
1022b274feedSAvi Kivity         0x02005858, 0x8301f858, 0x12105258, 0x9311f258,
1023b274feedSAvi Kivity         0x06005959, 0x8701f959, 0x16105359, 0x9711f359,
1024b274feedSAvi Kivity         0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a,
1025b274feedSAvi Kivity         0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b,
1026b274feedSAvi Kivity         0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c,
1027b274feedSAvi Kivity         0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d,
1028b274feedSAvi Kivity         0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e,
1029b274feedSAvi Kivity         0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f,
1030b274feedSAvi Kivity         0x06006060, 0x47010060, 0x16105a60, 0x9711fa60,
1031b274feedSAvi Kivity         0x02006161, 0x03010161, 0x12105b61, 0x9311fb61,
1032b274feedSAvi Kivity         0x02006262, 0x03010262, 0x16105c62, 0x9711fc62,
1033b274feedSAvi Kivity         0x06006363, 0x07010363, 0x12105d63, 0x9311fd63,
1034b274feedSAvi Kivity         0x02006464, 0x03010464, 0x12105e64, 0x9311fe64,
1035b274feedSAvi Kivity         0x06006565, 0x07010565, 0x16105f65, 0x9711ff65,
1036b274feedSAvi Kivity         0x06006666, 0x07010666, 0x16106066, 0x57110066,
1037b274feedSAvi Kivity         0x02006767, 0x03010767, 0x12106167, 0x13110167,
1038b274feedSAvi Kivity         0x02006868, 0x03010868, 0x12106268, 0x13110268,
1039b274feedSAvi Kivity         0x06006969, 0x07010969, 0x16106369, 0x17110369,
1040b274feedSAvi Kivity         0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a,
1041b274feedSAvi Kivity         0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b,
1042b274feedSAvi Kivity         0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c,
1043b274feedSAvi Kivity         0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d,
1044b274feedSAvi Kivity         0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e,
1045b274feedSAvi Kivity         0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f,
1046b274feedSAvi Kivity         0x02007070, 0x03011070, 0x16106a70, 0x17110a70,
1047b274feedSAvi Kivity         0x06007171, 0x07011171, 0x12106b71, 0x13110b71,
1048b274feedSAvi Kivity         0x06007272, 0x07011272, 0x16106c72, 0x17110c72,
1049b274feedSAvi Kivity         0x02007373, 0x03011373, 0x12106d73, 0x13110d73,
1050b274feedSAvi Kivity         0x06007474, 0x07011474, 0x12106e74, 0x13110e74,
1051b274feedSAvi Kivity         0x02007575, 0x03011575, 0x16106f75, 0x17110f75,
1052b274feedSAvi Kivity         0x02007676, 0x03011676, 0x12107076, 0x13111076,
1053b274feedSAvi Kivity         0x06007777, 0x07011777, 0x16107177, 0x17111177,
1054b274feedSAvi Kivity         0x06007878, 0x07011878, 0x16107278, 0x17111278,
1055b274feedSAvi Kivity         0x02007979, 0x03011979, 0x12107379, 0x13111379,
1056b274feedSAvi Kivity         0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a,
1057b274feedSAvi Kivity         0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b,
1058b274feedSAvi Kivity         0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c,
1059b274feedSAvi Kivity         0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d,
1060b274feedSAvi Kivity         0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e,
1061b274feedSAvi Kivity         0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f,
1062b274feedSAvi Kivity         0x82008080, 0x03012080, 0x12107a80, 0x13111a80,
1063b274feedSAvi Kivity         0x86008181, 0x07012181, 0x16107b81, 0x17111b81,
1064b274feedSAvi Kivity         0x86008282, 0x07012282, 0x12107c82, 0x13111c82,
1065b274feedSAvi Kivity         0x82008383, 0x03012383, 0x16107d83, 0x17111d83,
1066b274feedSAvi Kivity         0x86008484, 0x07012484, 0x16107e84, 0x17111e84,
1067b274feedSAvi Kivity         0x82008585, 0x03012585, 0x12107f85, 0x13111f85,
1068b274feedSAvi Kivity         0x82008686, 0x03012686, 0x92108086, 0x13112086,
1069b274feedSAvi Kivity         0x86008787, 0x07012787, 0x96108187, 0x17112187,
1070b274feedSAvi Kivity         0x86008888, 0x07012888, 0x96108288, 0x17112288,
1071b274feedSAvi Kivity         0x82008989, 0x03012989, 0x92108389, 0x13112389,
1072b274feedSAvi Kivity         0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a,
1073b274feedSAvi Kivity         0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b,
1074b274feedSAvi Kivity         0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c,
1075b274feedSAvi Kivity         0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d,
1076b274feedSAvi Kivity         0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e,
1077b274feedSAvi Kivity         0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f,
1078b274feedSAvi Kivity         0x86009090, 0x07013090, 0x92108a90, 0x13112a90,
1079b274feedSAvi Kivity         0x82009191, 0x03013191, 0x96108b91, 0x17112b91,
1080b274feedSAvi Kivity         0x82009292, 0x03013292, 0x92108c92, 0x13112c92,
1081b274feedSAvi Kivity         0x86009393, 0x07013393, 0x96108d93, 0x17112d93,
1082b274feedSAvi Kivity         0x82009494, 0x03013494, 0x96108e94, 0x17112e94,
1083b274feedSAvi Kivity         0x86009595, 0x07013595, 0x92108f95, 0x13112f95,
1084b274feedSAvi Kivity         0x86009696, 0x07013696, 0x96109096, 0x17113096,
1085b274feedSAvi Kivity         0x82009797, 0x03013797, 0x92109197, 0x13113197,
1086b274feedSAvi Kivity         0x82009898, 0x03013898, 0x92109298, 0x13113298,
1087b274feedSAvi Kivity         0x86009999, 0x07013999, 0x96109399, 0x17113399,
1088b274feedSAvi Kivity         0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a,
1089b274feedSAvi Kivity         0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b,
1090b274feedSAvi Kivity         0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c,
1091b274feedSAvi Kivity         0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d,
1092b274feedSAvi Kivity         0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e,
1093b274feedSAvi Kivity         0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f,
1094b274feedSAvi Kivity         0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0,
1095b274feedSAvi Kivity         0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1,
1096b274feedSAvi Kivity         0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2,
1097b274feedSAvi Kivity         0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3,
1098b274feedSAvi Kivity         0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4,
1099b274feedSAvi Kivity         0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5,
1100b274feedSAvi Kivity         0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6,
1101b274feedSAvi Kivity         0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7,
1102b274feedSAvi Kivity         0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8,
1103b274feedSAvi Kivity         0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9,
1104b274feedSAvi Kivity         0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa,
1105b274feedSAvi Kivity         0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab,
1106b274feedSAvi Kivity         0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac,
1107b274feedSAvi Kivity         0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad,
1108b274feedSAvi Kivity         0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae,
1109b274feedSAvi Kivity         0x130049af, 0x130149af, 0x131049af, 0x131149af,
1110b274feedSAvi Kivity         0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0,
1111b274feedSAvi Kivity         0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1,
1112b274feedSAvi Kivity         0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2,
1113b274feedSAvi Kivity         0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3,
1114b274feedSAvi Kivity         0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4,
1115b274feedSAvi Kivity         0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5,
1116b274feedSAvi Kivity         0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6,
1117b274feedSAvi Kivity         0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7,
1118b274feedSAvi Kivity         0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8,
1119b274feedSAvi Kivity         0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9,
1120b274feedSAvi Kivity         0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba,
1121b274feedSAvi Kivity         0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb,
1122b274feedSAvi Kivity         0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc,
1123b274feedSAvi Kivity         0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd,
1124b274feedSAvi Kivity         0x130058be, 0x130158be, 0x131058be, 0x131158be,
1125b274feedSAvi Kivity         0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf,
1126b274feedSAvi Kivity         0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0,
1127b274feedSAvi Kivity         0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1,
1128b274feedSAvi Kivity         0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2,
1129b274feedSAvi Kivity         0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3,
1130b274feedSAvi Kivity         0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4,
1131b274feedSAvi Kivity         0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5,
1132b274feedSAvi Kivity         0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6,
1133b274feedSAvi Kivity         0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7,
1134b274feedSAvi Kivity         0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8,
1135b274feedSAvi Kivity         0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9,
1136b274feedSAvi Kivity         0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca,
1137b274feedSAvi Kivity         0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb,
1138b274feedSAvi Kivity         0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc,
1139b274feedSAvi Kivity         0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd,
1140b274feedSAvi Kivity         0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce,
1141b274feedSAvi Kivity         0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf,
1142b274feedSAvi Kivity         0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0,
1143b274feedSAvi Kivity         0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1,
1144b274feedSAvi Kivity         0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2,
1145b274feedSAvi Kivity         0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3,
1146b274feedSAvi Kivity         0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4,
1147b274feedSAvi Kivity         0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5,
1148b274feedSAvi Kivity         0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6,
1149b274feedSAvi Kivity         0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7,
1150b274feedSAvi Kivity         0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8,
1151b274feedSAvi Kivity         0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9,
1152b274feedSAvi Kivity         0x170074da, 0x170174da, 0x171074da, 0x171174da,
1153b274feedSAvi Kivity         0x130075db, 0x130175db, 0x131075db, 0x131175db,
1154b274feedSAvi Kivity         0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc,
1155b274feedSAvi Kivity         0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd,
1156b274feedSAvi Kivity         0x170078de, 0x170178de, 0x171078de, 0x171178de,
1157b274feedSAvi Kivity         0x130079df, 0x130179df, 0x131079df, 0x131179df,
1158b274feedSAvi Kivity         0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0,
1159b274feedSAvi Kivity         0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1,
1160b274feedSAvi Kivity         0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2,
1161b274feedSAvi Kivity         0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3,
1162b274feedSAvi Kivity         0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4,
1163b274feedSAvi Kivity         0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5,
1164b274feedSAvi Kivity         0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6,
1165b274feedSAvi Kivity         0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7,
1166b274feedSAvi Kivity         0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8,
1167b274feedSAvi Kivity         0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9,
1168b274feedSAvi Kivity         0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea,
1169b274feedSAvi Kivity         0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb,
1170b274feedSAvi Kivity         0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec,
1171b274feedSAvi Kivity         0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed,
1172b274feedSAvi Kivity         0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee,
1173b274feedSAvi Kivity         0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef,
1174b274feedSAvi Kivity         0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0,
1175b274feedSAvi Kivity         0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1,
1176b274feedSAvi Kivity         0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2,
1177b274feedSAvi Kivity         0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3,
1178b274feedSAvi Kivity         0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4,
1179b274feedSAvi Kivity         0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5,
1180b274feedSAvi Kivity         0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6,
1181b274feedSAvi Kivity         0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7,
1182b274feedSAvi Kivity         0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8,
1183b274feedSAvi Kivity         0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9,
1184b274feedSAvi Kivity         0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa,
1185b274feedSAvi Kivity         0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb,
1186b274feedSAvi Kivity         0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc,
1187b274feedSAvi Kivity         0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd,
1188b274feedSAvi Kivity         0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe,
1189b274feedSAvi Kivity         0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff,
1190b274feedSAvi Kivity     };
1191b274feedSAvi Kivity 
1192b274feedSAvi Kivity     MK_INSN(das, "das");
1193b274feedSAvi Kivity 
1194b274feedSAvi Kivity     for (i = 0; i < 1024; ++i) {
1195b274feedSAvi Kivity         unsigned tmp = test_cases[i];
1196b274feedSAvi Kivity         inregs.eax = tmp & 0xff;
1197b274feedSAvi Kivity         inregs.eflags = (tmp >> 16) & 0xff;
1198d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_das);
1199b274feedSAvi Kivity 	if (!regs_equal(&inregs, &outregs, R_AX)
1200b274feedSAvi Kivity             || outregs.eax != ((tmp >> 8) & 0xff)
1201b274feedSAvi Kivity             || (outregs.eflags & 0xff) != (tmp >> 24)) {
1202*81050840SAvi Kivity 	    ++nr_fail;
1203*81050840SAvi Kivity 	    break;
1204b274feedSAvi Kivity         }
1205b274feedSAvi Kivity     }
1206*81050840SAvi Kivity     report("DAS", nr_fail == 0);
1207b274feedSAvi Kivity }
1208b274feedSAvi Kivity 
12090cbd5b06SMohammed Gamal void test_cwd_cdq()
12100cbd5b06SMohammed Gamal {
12110cbd5b06SMohammed Gamal 	struct regs inregs = { 0 }, outregs;
12120cbd5b06SMohammed Gamal 
12130cbd5b06SMohammed Gamal 	/* Sign-bit set */
12140cbd5b06SMohammed Gamal 	MK_INSN(cwd_1, "mov $0x8000, %ax\n\t"
12150cbd5b06SMohammed Gamal 		       "cwd\n\t");
12160cbd5b06SMohammed Gamal 
12170cbd5b06SMohammed Gamal 	/* Sign-bit not set */
12180cbd5b06SMohammed Gamal 	MK_INSN(cwd_2, "mov $0x1000, %ax\n\t"
12190cbd5b06SMohammed Gamal 		       "cwd\n\t");
12200cbd5b06SMohammed Gamal 
12210cbd5b06SMohammed Gamal 	/* Sign-bit set */
12220cbd5b06SMohammed Gamal 	MK_INSN(cdq_1, "mov $0x80000000, %eax\n\t"
12230cbd5b06SMohammed Gamal 		       "cdq\n\t");
12240cbd5b06SMohammed Gamal 
12250cbd5b06SMohammed Gamal 	/* Sign-bit not set */
12260cbd5b06SMohammed Gamal 	MK_INSN(cdq_2, "mov $0x10000000, %eax\n\t"
12270cbd5b06SMohammed Gamal 		       "cdq\n\t");
12280cbd5b06SMohammed Gamal 
1229d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cwd_1);
1230*81050840SAvi Kivity 	report("cwd 1",
1231*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_DX)
1232*81050840SAvi Kivity 	       && outregs.eax == 0x8000 && outregs.edx == 0xffff);
12330cbd5b06SMohammed Gamal 
1234d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cwd_2);
1235*81050840SAvi Kivity 	report("cwd 2",
1236*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_DX)
1237*81050840SAvi Kivity 	       && outregs.eax == 0x1000 && outregs.edx == 0);
12380cbd5b06SMohammed Gamal 
1239d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cdq_1);
1240*81050840SAvi Kivity 	report("cdq 1",
1241*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_DX)
1242*81050840SAvi Kivity 	       && outregs.eax == 0x80000000 && outregs.edx == 0xffffffff);
12430cbd5b06SMohammed Gamal 
1244d4dc402cSAvi Kivity 	exec_in_big_real_mode(&inregs, &outregs, &insn_cdq_2);
1245*81050840SAvi Kivity 	report("cdq 2",
1246*81050840SAvi Kivity 	       regs_equal(&inregs, &outregs, R_AX | R_DX)
1247*81050840SAvi Kivity 	       && outregs.eax == 0x10000000 && outregs.edx == 0);
12480cbd5b06SMohammed Gamal }
12490cbd5b06SMohammed Gamal 
12507d36db35SAvi Kivity void realmode_start(void)
12517d36db35SAvi Kivity {
12527d36db35SAvi Kivity 	test_null();
12537d36db35SAvi Kivity 
12547d36db35SAvi Kivity 	test_shld();
12557d36db35SAvi Kivity 	test_push_pop();
12567d36db35SAvi Kivity 	test_pusha_popa();
12577d36db35SAvi Kivity 	test_mov_imm();
12587d36db35SAvi Kivity 	test_cmp_imm();
12597d36db35SAvi Kivity 	test_add_imm();
12607d36db35SAvi Kivity 	test_sub_imm();
12617d36db35SAvi Kivity 	test_xor_imm();
12627d36db35SAvi Kivity 	test_io();
12637d36db35SAvi Kivity 	test_eflags_insn();
12647d36db35SAvi Kivity 	test_jcc_short();
12657d36db35SAvi Kivity 	test_jcc_near();
12667d36db35SAvi Kivity 	/* test_call() uses short jump so call it after testing jcc */
12677d36db35SAvi Kivity 	test_call();
12687d36db35SAvi Kivity 	/* long jmp test uses call near so test it after testing call */
12697d36db35SAvi Kivity 	test_long_jmp();
12707d36db35SAvi Kivity 	test_xchg();
12717d36db35SAvi Kivity 	test_iret();
127296b9ca1eSMohammed Gamal 	test_int();
1273fa74f8a6SMohammed Gamal 	test_imul();
127459317bd1SMohammed Gamal 	test_mul();
12750d4c7614SMohammed Gamal 	test_div();
12760d4c7614SMohammed Gamal 	test_idiv();
1277eacef4e2SWei Yongjun 	test_loopcc();
12786e293cf5SWei Yongjun 	test_cbw();
12790cbd5b06SMohammed Gamal 	test_cwd_cdq();
1280b274feedSAvi Kivity 	test_das();
12817d36db35SAvi Kivity 
12827d36db35SAvi Kivity 	exit(0);
12837d36db35SAvi Kivity }
12847d36db35SAvi Kivity 
12857d36db35SAvi Kivity unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff };
12867d36db35SAvi Kivity 
12877d36db35SAvi Kivity struct __attribute__((packed)) {
12887d36db35SAvi Kivity 	unsigned short limit;
12897d36db35SAvi Kivity 	void *base;
12907d36db35SAvi Kivity } r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt };
12917d36db35SAvi Kivity 
12927d36db35SAvi Kivity asm(
12937d36db35SAvi Kivity 	".section .init \n\t"
12947d36db35SAvi Kivity 
12957d36db35SAvi Kivity 	".code32 \n\t"
12967d36db35SAvi Kivity 
12977d36db35SAvi Kivity 	"mb_magic = 0x1BADB002 \n\t"
12987d36db35SAvi Kivity 	"mb_flags = 0x0 \n\t"
12997d36db35SAvi Kivity 
13007d36db35SAvi Kivity 	"# multiboot header \n\t"
13017d36db35SAvi Kivity 	".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t"
13027d36db35SAvi Kivity 
13037d36db35SAvi Kivity 	".globl start \n\t"
13047d36db35SAvi Kivity 	".data \n\t"
13057d36db35SAvi Kivity 	". = . + 4096 \n\t"
13067d36db35SAvi Kivity 	"stacktop: \n\t"
13077d36db35SAvi Kivity 
13087d36db35SAvi Kivity 	".text \n\t"
13097d36db35SAvi Kivity 	"start: \n\t"
13107d36db35SAvi Kivity 	"lgdt r_gdt_descr \n\t"
13117d36db35SAvi Kivity 	"ljmp $8, $1f; 1: \n\t"
13127d36db35SAvi Kivity 	".code16gcc \n\t"
13137d36db35SAvi Kivity 	"mov $16, %eax \n\t"
13147d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
13157d36db35SAvi Kivity 	"mov %ax, %es \n\t"
13167d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
13177d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
13187d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
13197d36db35SAvi Kivity 	"mov %cr0, %eax \n\t"
13207d36db35SAvi Kivity 	"btc $0, %eax \n\t"
13217d36db35SAvi Kivity 	"mov %eax, %cr0 \n\t"
13227d36db35SAvi Kivity 	"ljmp $0, $realmode_entry \n\t"
13237d36db35SAvi Kivity 
13247d36db35SAvi Kivity 	"realmode_entry: \n\t"
13257d36db35SAvi Kivity 
13267d36db35SAvi Kivity 	"xor %ax, %ax \n\t"
13277d36db35SAvi Kivity 	"mov %ax, %ds \n\t"
13287d36db35SAvi Kivity 	"mov %ax, %es \n\t"
13297d36db35SAvi Kivity 	"mov %ax, %ss \n\t"
13307d36db35SAvi Kivity 	"mov %ax, %fs \n\t"
13317d36db35SAvi Kivity 	"mov %ax, %gs \n\t"
13327d36db35SAvi Kivity 	"mov $stacktop, %esp\n\t"
13337d36db35SAvi Kivity 	"ljmp $0, $realmode_start \n\t"
13347d36db35SAvi Kivity 
13357d36db35SAvi Kivity 	".code16gcc \n\t"
13367d36db35SAvi Kivity 	);
1337