xref: /kvm-unit-tests/x86/realmode.c (revision b274feed8adb0f7e4d951dcb2ae84276f7cf5774) !
1 asm(".code16gcc");
2 
3 typedef unsigned char u8;
4 typedef unsigned short u16;
5 typedef unsigned u32;
6 typedef unsigned long long u64;
7 
8 void test_function(void);
9 
10 asm(
11 	"test_function: \n\t"
12 	"mov $0x1234, %eax \n\t"
13 	"ret"
14    );
15 
16 static int strlen(const char *str)
17 {
18 	int n;
19 
20 	for (n = 0; *str; ++str)
21 		++n;
22 	return n;
23 }
24 
25 static void print_serial(const char *buf)
26 {
27 	unsigned long len = strlen(buf);
28 
29 	asm volatile ("cld; addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1));
30 }
31 
32 static void exit(int code)
33 {
34         asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4));
35 }
36 
37 struct regs {
38 	u32 eax, ebx, ecx, edx;
39 	u32 esi, edi, esp, ebp;
40 	u32 eip, eflags;
41 };
42 
43 static u64 gdt[] = {
44 	0,
45 	0x00cf9b000000ffffull, // flat 32-bit code segment
46 	0x00cf93000000ffffull, // flat 32-bit data segment
47 };
48 
49 static struct {
50 	u16 limit;
51 	void *base;
52 } __attribute__((packed)) gdt_descr = {
53 	sizeof(gdt) - 1,
54 	gdt,
55 };
56 
57 static void exec_in_big_real_mode(const struct regs *inregs,
58 				  struct regs *outregs,
59 				  const u8 *insn, int insn_len)
60 {
61 	unsigned long tmp;
62 	static struct regs save;
63 	int i;
64 	extern u8 test_insn[], test_insn_end[];
65 
66 	for (i = 0; i < insn_len; ++i)
67 		test_insn[i] = insn[i];
68 	for (; i < test_insn_end - test_insn; ++i)
69 		test_insn[i] = 0x90; // nop
70 
71 	save = *inregs;
72 	asm volatile(
73 		"lgdtl %[gdt_descr] \n\t"
74 		"mov %%cr0, %[tmp] \n\t"
75 		"or $1, %[tmp] \n\t"
76 		"mov %[tmp], %%cr0 \n\t"
77 		"mov %[bigseg], %%gs \n\t"
78 		"and $-2, %[tmp] \n\t"
79 		"mov %[tmp], %%cr0 \n\t"
80 
81                 "pushw %[save]+36; popfw \n\t"
82 		"xchg %%eax, %[save]+0 \n\t"
83 		"xchg %%ebx, %[save]+4 \n\t"
84 		"xchg %%ecx, %[save]+8 \n\t"
85 		"xchg %%edx, %[save]+12 \n\t"
86 		"xchg %%esi, %[save]+16 \n\t"
87 		"xchg %%edi, %[save]+20 \n\t"
88 		"xchg %%esp, %[save]+24 \n\t"
89 		"xchg %%ebp, %[save]+28 \n\t"
90 
91 		"test_insn: . = . + 32\n\t"
92 		"test_insn_end: \n\t"
93 
94 		"xchg %%eax, %[save]+0 \n\t"
95 		"xchg %%ebx, %[save]+4 \n\t"
96 		"xchg %%ecx, %[save]+8 \n\t"
97 		"xchg %%edx, %[save]+12 \n\t"
98 		"xchg %%esi, %[save]+16 \n\t"
99 		"xchg %%edi, %[save]+20 \n\t"
100 		"xchg %%esp, %[save]+24 \n\t"
101 		"xchg %%ebp, %[save]+28 \n\t"
102 
103 		/* Save EFLAGS in outregs*/
104 		"pushfl \n\t"
105 		"popl %[save]+36 \n\t"
106 
107 		"xor %[tmp], %[tmp] \n\t"
108 		"mov %[tmp], %%gs \n\t"
109 		: [tmp]"=&r"(tmp), [save]"+m"(save)
110 		: [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16)
111 		: "cc", "memory"
112 		);
113 	*outregs = save;
114 }
115 
116 #define R_AX 1
117 #define R_BX 2
118 #define R_CX 4
119 #define R_DX 8
120 #define R_SI 16
121 #define R_DI 32
122 #define R_SP 64
123 #define R_BP 128
124 
125 int regs_equal(const struct regs *r1, const struct regs *r2, int ignore)
126 {
127 	const u32 *p1 = &r1->eax, *p2 = &r2->eax;  // yuck
128 	int i;
129 
130 	for (i = 0; i < 8; ++i)
131 		if (!(ignore & (1 << i)) && p1[i] != p2[i])
132 			return 0;
133 	return 1;
134 }
135 
136 #define MK_INSN(name, str)                         \
137 	asm (				           \
138 		".text 1\n\t"                      \
139 		"insn_" #name ": " str " \n\t"	   \
140 		"insn_" #name "_end: \n\t"	   \
141 		".text\n\t"                        \
142 		);				   \
143 	extern u8 insn_##name[], insn_##name##_end[]
144 
145 void test_xchg(void)
146 {
147 	struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}, outregs;
148 
149 	MK_INSN(xchg_test1, "xchg %eax,%eax\n\t");
150 	MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t");
151 	MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t");
152 	MK_INSN(xchg_test4, "xchg %eax,%edx\n\t");
153 	MK_INSN(xchg_test5, "xchg %eax,%esi\n\t");
154 	MK_INSN(xchg_test6, "xchg %eax,%edi\n\t");
155 	MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t");
156 	MK_INSN(xchg_test8, "xchg %eax,%esp\n\t");
157 
158 	exec_in_big_real_mode(&inregs, &outregs,
159 			      insn_xchg_test1,
160                               insn_xchg_test1_end - insn_xchg_test1);
161 
162 	if (!regs_equal(&inregs, &outregs, 0))
163 		print_serial("xchg test 1: FAIL\n");
164 	else
165 		print_serial("xchg test 1: PASS\n");
166 
167 	exec_in_big_real_mode(&inregs, &outregs,
168 			      insn_xchg_test2,
169                               insn_xchg_test2_end - insn_xchg_test2);
170 
171 	if (!regs_equal(&inregs, &outregs, R_AX | R_BX) ||
172             outregs.eax != inregs.ebx ||
173             outregs.ebx != inregs.eax)
174 		print_serial("xchg test 2: FAIL\n");
175 	else
176 		print_serial("xchg test 2: PASS\n");
177 
178 	exec_in_big_real_mode(&inregs, &outregs,
179 			      insn_xchg_test3,
180                               insn_xchg_test3_end - insn_xchg_test3);
181 
182 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX) ||
183             outregs.eax != inregs.ecx ||
184             outregs.ecx != inregs.eax)
185 		print_serial("xchg test 3: FAIL\n");
186 	else
187 		print_serial("xchg test 3: PASS\n");
188 
189 	exec_in_big_real_mode(&inregs, &outregs,
190 			      insn_xchg_test4,
191                               insn_xchg_test4_end - insn_xchg_test4);
192 
193 	if (!regs_equal(&inregs, &outregs, R_AX | R_DX) ||
194             outregs.eax != inregs.edx ||
195             outregs.edx != inregs.eax)
196 		print_serial("xchg test 4: FAIL\n");
197 	else
198 		print_serial("xchg test 4: PASS\n");
199 
200 	exec_in_big_real_mode(&inregs, &outregs,
201 			      insn_xchg_test5,
202                               insn_xchg_test5_end - insn_xchg_test5);
203 
204 	if (!regs_equal(&inregs, &outregs, R_AX | R_SI) ||
205             outregs.eax != inregs.esi ||
206             outregs.esi != inregs.eax)
207 		print_serial("xchg test 5: FAIL\n");
208 	else
209 		print_serial("xchg test 5: PASS\n");
210 
211 	exec_in_big_real_mode(&inregs, &outregs,
212 			      insn_xchg_test6,
213                               insn_xchg_test6_end - insn_xchg_test6);
214 
215 	if (!regs_equal(&inregs, &outregs, R_AX | R_DI) ||
216             outregs.eax != inregs.edi ||
217             outregs.edi != inregs.eax)
218 		print_serial("xchg test 6: FAIL\n");
219 	else
220 		print_serial("xchg test 6: PASS\n");
221 
222 	exec_in_big_real_mode(&inregs, &outregs,
223 			      insn_xchg_test7,
224                               insn_xchg_test7_end - insn_xchg_test7);
225 
226 	if (!regs_equal(&inregs, &outregs, R_AX | R_BP) ||
227             outregs.eax != inregs.ebp ||
228             outregs.ebp != inregs.eax)
229 		print_serial("xchg test 7: FAIL\n");
230 	else
231 		print_serial("xchg test 7: PASS\n");
232 
233 	exec_in_big_real_mode(&inregs, &outregs,
234 			      insn_xchg_test8,
235                               insn_xchg_test8_end - insn_xchg_test8);
236 
237 	if (!regs_equal(&inregs, &outregs, R_AX | R_SP) ||
238             outregs.eax != inregs.esp ||
239             outregs.esp != inregs.eax)
240 		print_serial("xchg test 8: FAIL\n");
241 	else
242 		print_serial("xchg test 8: PASS\n");
243 }
244 
245 void test_shld(void)
246 {
247 	struct regs inregs = { .eax = 0xbe, .edx = 0xef000000 }, outregs;
248 	MK_INSN(shld_test, "shld $8,%edx,%eax\n\t");
249 
250 	exec_in_big_real_mode(&inregs, &outregs,
251 			      insn_shld_test,
252 			      insn_shld_test_end - insn_shld_test);
253 	if (outregs.eax != 0xbeef)
254 		print_serial("shld: FAIL\n");
255 	else
256 		print_serial("shld: PASS\n");
257 }
258 
259 void test_mov_imm(void)
260 {
261 	struct regs inregs = { 0 }, outregs;
262 	MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax");
263 	MK_INSN(mov_r16_imm_1, "mov $1234, %ax");
264 	MK_INSN(mov_r8_imm_1, "mov $0x12, %ah");
265 	MK_INSN(mov_r8_imm_2, "mov $0x34, %al");
266 	MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t");
267 
268 	exec_in_big_real_mode(&inregs, &outregs,
269 			      insn_mov_r16_imm_1,
270 			      insn_mov_r16_imm_1_end - insn_mov_r16_imm_1);
271 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234)
272 		print_serial("mov test 1: FAIL\n");
273 	else
274 		print_serial("mov test 1: PASS\n");
275 
276 	/* test mov $imm, %eax */
277 	exec_in_big_real_mode(&inregs, &outregs,
278 			      insn_mov_r32_imm_1,
279 			      insn_mov_r32_imm_1_end - insn_mov_r32_imm_1);
280 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567890)
281 		print_serial("mov test 2: FAIL\n");
282 	else
283 		print_serial("mov test 2: PASS\n");
284 
285 	/* test mov $imm, %al/%ah */
286 	exec_in_big_real_mode(&inregs, &outregs,
287 			      insn_mov_r8_imm_1,
288 			      insn_mov_r8_imm_1_end - insn_mov_r8_imm_1);
289 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1200)
290 		print_serial("mov test 3: FAIL\n");
291 	else
292 		print_serial("mov test 3: PASS\n");
293 
294 	exec_in_big_real_mode(&inregs, &outregs,
295 			      insn_mov_r8_imm_2,
296 			      insn_mov_r8_imm_2_end - insn_mov_r8_imm_2);
297 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x34)
298 		print_serial("mov test 4: FAIL\n");
299 	else
300 		print_serial("mov test 4: PASS\n");
301 
302 	exec_in_big_real_mode(&inregs, &outregs,
303 			      insn_mov_r8_imm_3,
304 			      insn_mov_r8_imm_3_end - insn_mov_r8_imm_3);
305 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
306 		print_serial("mov test 5: FAIL\n");
307 	else
308 		print_serial("mov test 5: PASS\n");
309 }
310 
311 void test_sub_imm(void)
312 {
313 	struct regs inregs = { 0 }, outregs;
314 	MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t");
315 	MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t");
316 	MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t");
317 	MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t");
318 
319 	exec_in_big_real_mode(&inregs, &outregs,
320 			      insn_sub_r16_imm_1,
321 			      insn_sub_r16_imm_1_end - insn_sub_r16_imm_1);
322 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1224)
323 		print_serial("sub test 1: FAIL\n");
324 	else
325 		print_serial("sub test 1: PASS\n");
326 
327 	/* test mov $imm, %eax */
328 	exec_in_big_real_mode(&inregs, &outregs,
329 			      insn_sub_r32_imm_1,
330 			      insn_sub_r32_imm_1_end - insn_sub_r32_imm_1);
331 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567880)
332 		print_serial("sub test 2: FAIL\n");
333 	else
334 		print_serial("sub test 2: PASS\n");
335 
336 	/* test mov $imm, %al/%ah */
337 	exec_in_big_real_mode(&inregs, &outregs,
338 			      insn_sub_r8_imm_1,
339 			      insn_sub_r8_imm_1_end - insn_sub_r8_imm_1);
340 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x0200)
341 		print_serial("sub test 3: FAIL\n");
342 	else
343 		print_serial("sub test 3: PASS\n");
344 
345 	exec_in_big_real_mode(&inregs, &outregs,
346 			      insn_sub_r8_imm_2,
347 			      insn_sub_r8_imm_2_end - insn_sub_r8_imm_2);
348 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x24)
349 		print_serial("sub test 4: FAIL\n");
350 	else
351 		print_serial("sub test 4: PASS\n");
352 }
353 
354 
355 void test_xor_imm(void)
356 {
357 	struct regs inregs = { 0 }, outregs;
358 	MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t");
359 	MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t");
360 	MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t");
361 	MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t");
362 
363 	exec_in_big_real_mode(&inregs, &outregs,
364 			      insn_xor_r16_imm_1,
365 			      insn_xor_r16_imm_1_end - insn_xor_r16_imm_1);
366 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0)
367 		print_serial("xor test 1: FAIL\n");
368 	else
369 		print_serial("xor test 1: PASS\n");
370 
371 	/* test mov $imm, %eax */
372 	exec_in_big_real_mode(&inregs, &outregs,
373 			      insn_xor_r32_imm_1,
374 			      insn_xor_r32_imm_1_end - insn_xor_r32_imm_1);
375 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0)
376 		print_serial("xor test 2: FAIL\n");
377 	else
378 		print_serial("xor test 2: PASS\n");
379 
380 	/* test mov $imm, %al/%ah */
381 	exec_in_big_real_mode(&inregs, &outregs,
382 			      insn_xor_r8_imm_1,
383 			      insn_xor_r8_imm_1_end - insn_xor_r8_imm_1);
384 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0)
385 		print_serial("xor test 3: FAIL\n");
386 	else
387 		print_serial("xor test 3: PASS\n");
388 
389 	exec_in_big_real_mode(&inregs, &outregs,
390 			      insn_xor_r8_imm_2,
391 			      insn_xor_r8_imm_2_end - insn_xor_r8_imm_2);
392 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0)
393 		print_serial("xor test 4: FAIL\n");
394 	else
395 		print_serial("xor test 4: PASS\n");
396 }
397 
398 void test_cmp_imm(void)
399 {
400 	struct regs inregs = { 0 }, outregs;
401 	MK_INSN(cmp_test1, "mov $0x34, %al\n\t"
402 			   "cmp $0x34, %al\n\t");
403 	MK_INSN(cmp_test2, "mov $0x34, %al\n\t"
404 			   "cmp $0x39, %al\n\t");
405 	MK_INSN(cmp_test3, "mov $0x34, %al\n\t"
406 			   "cmp $0x24, %al\n\t");
407 
408 	/* test cmp imm8 with AL */
409 	/* ZF: (bit 6) Zero Flag becomes 1 if an operation results
410 	 * in a 0 writeback, or 0 register
411 	 */
412 	exec_in_big_real_mode(&inregs, &outregs,
413 			      insn_cmp_test1,
414 			      insn_cmp_test1_end - insn_cmp_test1);
415 	if ((outregs.eflags & (1<<6)) != (1<<6))
416 		print_serial("cmp test 1: FAIL\n");
417 	else
418 		print_serial("cmp test 1: PASS\n");
419 
420 	exec_in_big_real_mode(&inregs, &outregs,
421 			      insn_cmp_test2,
422 			      insn_cmp_test2_end - insn_cmp_test2);
423 	if ((outregs.eflags & (1<<6)) != 0)
424 		print_serial("cmp test 2: FAIL\n");
425 	else
426 		print_serial("cmp test 2: PASS\n");
427 
428 	exec_in_big_real_mode(&inregs, &outregs,
429 			      insn_cmp_test3,
430 			      insn_cmp_test3_end - insn_cmp_test3);
431 	if ((outregs.eflags & (1<<6)) != 0)
432 		print_serial("cmp test 3: FAIL\n");
433 	else
434 		print_serial("cmp test 3: PASS\n");
435 }
436 
437 void test_add_imm(void)
438 {
439 	struct regs inregs = { 0 }, outregs;
440 	MK_INSN(add_test1, "mov $0x43211234, %eax \n\t"
441 			   "add $0x12344321, %eax \n\t");
442 	MK_INSN(add_test2, "mov $0x12, %eax \n\t"
443 			   "add $0x21, %al\n\t");
444 
445 	exec_in_big_real_mode(&inregs, &outregs,
446 			      insn_add_test1,
447 			      insn_add_test1_end - insn_add_test1);
448 	if (outregs.eax != 0x55555555)
449 		print_serial("add test 1: FAIL\n");
450 	else
451 		print_serial("add test 1: PASS\n");
452 
453 	exec_in_big_real_mode(&inregs, &outregs,
454 			      insn_add_test2,
455 			      insn_add_test2_end - insn_add_test2);
456 	if (outregs.eax != 0x33)
457 		print_serial("add test 2: FAIL\n");
458 	else
459 		print_serial("add test 2: PASS\n");
460 }
461 
462 void test_eflags_insn(void)
463 {
464 	struct regs inregs = { 0 }, outregs;
465 	MK_INSN(clc, "clc");
466 	MK_INSN(stc, "stc");
467 	MK_INSN(cli, "cli");
468 	MK_INSN(sti, "sti");
469 	MK_INSN(cld, "cld");
470 	MK_INSN(std, "std");
471 
472 	exec_in_big_real_mode(&inregs, &outregs,
473 			      insn_clc,
474 			      insn_clc_end - insn_clc);
475 	if (outregs.eflags & 1)
476 		print_serial("clc test: FAIL\n");
477 	else
478 		print_serial("clc test: PASS\n");
479 
480 	exec_in_big_real_mode(&inregs, &outregs,
481 			      insn_stc,
482 			      insn_stc_end - insn_stc);
483 	if (!(outregs.eflags & 1))
484 		print_serial("stc test: FAIL\n");
485 	else
486 		print_serial("stc test: PASS\n");
487 
488 	exec_in_big_real_mode(&inregs, &outregs,
489 			      insn_cli,
490 			      insn_cli_end - insn_cli);
491 	if (outregs.eflags & (1 << 9))
492 		print_serial("cli test: FAIL\n");
493 	else
494 		print_serial("cli test: PASS\n");
495 
496 	exec_in_big_real_mode(&inregs, &outregs,
497 			      insn_sti,
498 			      insn_sti_end - insn_sti);
499 	if (!(outregs.eflags & (1 << 9)))
500 		print_serial("sti test: FAIL\n");
501 	else
502 		print_serial("sti test: PASS\n");
503 
504 	exec_in_big_real_mode(&inregs, &outregs,
505 			      insn_cld,
506 			      insn_cld_end - insn_cld);
507 	if (outregs.eflags & (1 << 10))
508 		print_serial("cld test: FAIL\n");
509 	else
510 		print_serial("cld test: PASS\n");
511 
512 	exec_in_big_real_mode(&inregs, &outregs,
513 			      insn_std,
514 			      insn_std_end - insn_std);
515 	if (!(outregs.eflags & (1 << 10)))
516 		print_serial("std test: FAIL\n");
517 	else
518 		print_serial("std test: PASS\n");
519 }
520 
521 void test_io(void)
522 {
523 	struct regs inregs = { 0 }, outregs;
524 	MK_INSN(io_test1, "mov $0xff, %al \n\t"
525 		          "out %al, $0xe0 \n\t"
526 		          "mov $0x00, %al \n\t"
527 			  "in $0xe0, %al \n\t");
528 	MK_INSN(io_test2, "mov $0xffff, %ax \n\t"
529 			  "out %ax, $0xe0 \n\t"
530 			  "mov $0x0000, %ax \n\t"
531 			  "in $0xe0, %ax \n\t");
532 	MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t"
533 			  "out %eax, $0xe0 \n\t"
534 			  "mov $0x000000, %eax \n\t"
535 			  "in $0xe0, %eax \n\t");
536 	MK_INSN(io_test4, "mov $0xe0, %dx \n\t"
537 			  "mov $0xff, %al \n\t"
538 			  "out %al, %dx \n\t"
539 			  "mov $0x00, %al \n\t"
540 			  "in %dx, %al \n\t");
541 	MK_INSN(io_test5, "mov $0xe0, %dx \n\t"
542 			  "mov $0xffff, %ax \n\t"
543 			  "out %ax, %dx \n\t"
544 			  "mov $0x0000, %ax \n\t"
545 			  "in %dx, %ax \n\t");
546 	MK_INSN(io_test6, "mov $0xe0, %dx \n\t"
547 			  "mov $0xffffffff, %eax \n\t"
548 			  "out %eax, %dx \n\t"
549 			  "mov $0x00000000, %eax \n\t"
550 			  "in %dx, %eax \n\t");
551 
552 	exec_in_big_real_mode(&inregs, &outregs,
553 			      insn_io_test1,
554 			      insn_io_test1_end - insn_io_test1);
555 
556 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xff)
557 		print_serial("I/O test 1: FAIL\n");
558 	else
559 		print_serial("I/O test 1: PASS\n");
560 
561 	exec_in_big_real_mode(&inregs, &outregs,
562 			      insn_io_test2,
563 			      insn_io_test2_end - insn_io_test2);
564 
565 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffff)
566 		print_serial("I/O test 2: FAIL\n");
567 	else
568 		print_serial("I/O test 2: PASS\n");
569 
570 	exec_in_big_real_mode(&inregs, &outregs,
571 			      insn_io_test3,
572 			      insn_io_test3_end - insn_io_test3);
573 
574 	if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffffffff)
575 		print_serial("I/O test 3: FAIL\n");
576 	else
577 		print_serial("I/O test 3: PASS\n");
578 
579 	exec_in_big_real_mode(&inregs, &outregs,
580 			      insn_io_test4,
581 			      insn_io_test4_end - insn_io_test4);
582 
583 	if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xff)
584 		print_serial("I/O test 4: FAIL\n");
585 	else
586 		print_serial("I/O test 4: PASS\n");
587 
588 	exec_in_big_real_mode(&inregs, &outregs,
589 			      insn_io_test5,
590 			      insn_io_test5_end - insn_io_test5);
591 
592 	if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffff)
593 		print_serial("I/O test 5: FAIL\n");
594 	else
595 		print_serial("I/O test 5: PASS\n");
596 
597 	exec_in_big_real_mode(&inregs, &outregs,
598 			      insn_io_test6,
599 			      insn_io_test6_end - insn_io_test6);
600 
601 	if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffffffff)
602 		print_serial("I/O test 6: FAIL\n");
603 	else
604 		print_serial("I/O test 6: PASS\n");
605 }
606 
607 void test_call(void)
608 {
609 	struct regs inregs = { 0 }, outregs;
610 	u32 esp[16];
611 
612 	inregs.esp = (u32)esp;
613 
614 	MK_INSN(call1, "mov $test_function, %eax \n\t"
615 		       "call *%eax\n\t");
616 	MK_INSN(call_near1, "jmp 2f\n\t"
617 			    "1: mov $0x1234, %eax\n\t"
618 			    "ret\n\t"
619 			    "2: call 1b\t");
620 	MK_INSN(call_near2, "call 1f\n\t"
621 			    "jmp 2f\n\t"
622 			    "1: mov $0x1234, %eax\n\t"
623 			    "ret\n\t"
624 			    "2:\t");
625 
626 	exec_in_big_real_mode(&inregs, &outregs,
627 			      insn_call1,
628 			      insn_call1_end - insn_call1);
629 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
630 		print_serial("Call Test 1: FAIL\n");
631 	else
632 		print_serial("Call Test 1: PASS\n");
633 
634 	exec_in_big_real_mode(&inregs, &outregs,
635 			insn_call_near1, insn_call_near1_end - insn_call_near1);
636 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
637 		print_serial("Call near Test 1: FAIL\n");
638 	else
639 		print_serial("Call near Test 1: PASS\n");
640 
641 	exec_in_big_real_mode(&inregs, &outregs,
642 			insn_call_near2, insn_call_near2_end - insn_call_near2);
643 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
644 		print_serial("Call near Test 2: FAIL\n");
645 	else
646 		print_serial("Call near Test 2: PASS\n");
647 }
648 
649 void test_jcc_short(void)
650 {
651 	struct regs inregs = { 0 }, outregs;
652 	MK_INSN(jnz_short1, "jnz 1f\n\t"
653 			    "mov $0x1234, %eax\n\t"
654 		            "1:\n\t");
655 	MK_INSN(jnz_short2, "1:\n\t"
656 			    "cmp $0x1234, %eax\n\t"
657 			    "mov $0x1234, %eax\n\t"
658 		            "jnz 1b\n\t");
659 	MK_INSN(jmp_short1, "jmp 1f\n\t"
660 		      "mov $0x1234, %eax\n\t"
661 		      "1:\n\t");
662 
663 	exec_in_big_real_mode(&inregs, &outregs,
664 			insn_jnz_short1, insn_jnz_short1_end - insn_jnz_short1);
665 	if(!regs_equal(&inregs, &outregs, 0))
666 		print_serial("JNZ short Test 1: FAIL\n");
667 	else
668 		print_serial("JNZ short Test 1: PASS\n");
669 
670 	exec_in_big_real_mode(&inregs, &outregs,
671 			insn_jnz_short2, insn_jnz_short2_end - insn_jnz_short2);
672 	if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6)))
673 		print_serial("JNZ short Test 2: FAIL\n");
674 	else
675 		print_serial("JNZ short Test 2: PASS\n");
676 
677 	exec_in_big_real_mode(&inregs, &outregs,
678 			insn_jmp_short1, insn_jmp_short1_end - insn_jmp_short1);
679 	if(!regs_equal(&inregs, &outregs, 0))
680 		print_serial("JMP short Test 1: FAIL\n");
681 	else
682 		print_serial("JMP short Test 1: PASS\n");
683 }
684 
685 void test_jcc_near(void)
686 {
687 	struct regs inregs = { 0 }, outregs;
688 	/* encode near jmp manually. gas will not do it if offsets < 127 byte */
689 	MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t"
690 		           "mov $0x1234, %eax\n\t");
691 	MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t"
692 			   "mov $0x1234, %eax\n\t"
693 		           ".byte 0x0f, 0x85, 0xf0, 0xff\n\t");
694 	MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t"
695 		           "mov $0x1234, %eax\n\t");
696 
697 	exec_in_big_real_mode(&inregs, &outregs,
698 			insn_jnz_near1, insn_jnz_near1_end - insn_jnz_near1);
699 	if(!regs_equal(&inregs, &outregs, 0))
700 		print_serial("JNZ near Test 1: FAIL\n");
701 	else
702 		print_serial("JNZ near Test 1: PASS\n");
703 
704 	exec_in_big_real_mode(&inregs, &outregs,
705 			insn_jnz_near2, insn_jnz_near2_end - insn_jnz_near2);
706 	if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6)))
707 		print_serial("JNZ near Test 2: FAIL\n");
708 	else
709 		print_serial("JNZ near Test 2: PASS\n");
710 
711 	exec_in_big_real_mode(&inregs, &outregs,
712 			insn_jmp_near1, insn_jmp_near1_end - insn_jmp_near1);
713 	if(!regs_equal(&inregs, &outregs, 0))
714 		print_serial("JMP near Test 1: FAIL\n");
715 	else
716 		print_serial("JMP near Test 1: PASS\n");
717 }
718 
719 void test_long_jmp()
720 {
721 	struct regs inregs = { 0 }, outregs;
722 	u32 esp[16];
723 
724 	inregs.esp = (u32)esp;
725 	MK_INSN(long_jmp, "call 1f\n\t"
726 			  "jmp 2f\n\t"
727 			  "1: jmp $0, $test_function\n\t"
728 		          "2:\n\t");
729 	exec_in_big_real_mode(&inregs, &outregs,
730 			      insn_long_jmp,
731 			      insn_long_jmp_end - insn_long_jmp);
732 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234)
733 		print_serial("Long JMP Test: FAIL\n");
734 	else
735 		print_serial("Long JMP Test: PASS\n");
736 }
737 
738 void test_push_pop()
739 {
740 	struct regs inregs = { 0 }, outregs;
741 	MK_INSN(push32, "mov $0x12345678, %eax\n\t"
742 			"push %eax\n\t"
743 			"pop %ebx\n\t");
744 	MK_INSN(push16, "mov $0x1234, %ax\n\t"
745 			"push %ax\n\t"
746 			"pop %bx\n\t");
747 
748 	MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten
749 			 "mov $0x123, %ax\n\t"
750 			 "mov %ax, %es\n\t"
751 			 "push %es\n\t"
752 			 "pop %bx \n\t"
753 			 );
754 	MK_INSN(pop_es, "push %ax\n\t"
755 			"pop %es\n\t"
756 			"mov %es, %bx\n\t"
757 			);
758 	MK_INSN(push_pop_ss, "push %ss\n\t"
759 			     "pushw %ax\n\t"
760 			     "popw %ss\n\t"
761 			     "mov %ss, %bx\n\t"
762 			     "pop %ss\n\t"
763 			);
764 	MK_INSN(push_pop_fs, "push %fs\n\t"
765 			     "pushl %eax\n\t"
766 			     "popl %fs\n\t"
767 			     "mov %fs, %ebx\n\t"
768 			     "pop %fs\n\t"
769 			);
770 
771 	exec_in_big_real_mode(&inregs, &outregs,
772 			      insn_push32,
773 			      insn_push32_end - insn_push32);
774 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x12345678)
775 		print_serial("Push/Pop Test 1: FAIL\n");
776 	else
777 		print_serial("Push/Pop Test 1: PASS\n");
778 
779 	exec_in_big_real_mode(&inregs, &outregs,
780 			      insn_push16,
781 			      insn_push16_end - insn_push16);
782 
783 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x1234)
784 		print_serial("Push/Pop Test 2: FAIL\n");
785 	else
786 		print_serial("Push/Pop Test 2: PASS\n");
787 
788 	exec_in_big_real_mode(&inregs, &outregs,
789 			      insn_push_es,
790 			      insn_push_es_end - insn_push_es);
791 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) ||  outregs.ebx != outregs.eax || outregs.eax != 0x123)
792 		print_serial("Push/Pop Test 3: FAIL\n");
793 	else
794 		print_serial("Push/Pop Test 3: PASS\n");
795 
796 	exec_in_big_real_mode(&inregs, &outregs,
797 			      insn_pop_es,
798 			      insn_pop_es_end - insn_pop_es);
799 
800 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax)
801 		print_serial("Push/Pop Test 4: FAIL\n");
802 	else
803 		print_serial("Push/Pop Test 4: PASS\n");
804 
805 	exec_in_big_real_mode(&inregs, &outregs,
806 			      insn_push_pop_ss,
807 			      insn_push_pop_ss_end - insn_push_pop_ss);
808 
809 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax)
810 		print_serial("Push/Pop Test 5: FAIL\n");
811 	else
812 		print_serial("Push/Pop Test 5: PASS\n");
813 
814 	exec_in_big_real_mode(&inregs, &outregs,
815 			      insn_push_pop_fs,
816 			      insn_push_pop_fs_end - insn_push_pop_fs);
817 
818 	if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax)
819 		print_serial("Push/Pop Test 6: FAIL\n");
820 	else
821 		print_serial("Push/Pop Test 6: PASS\n");
822 }
823 
824 void test_null(void)
825 {
826 	struct regs inregs = { 0 }, outregs;
827 	exec_in_big_real_mode(&inregs, &outregs, 0, 0);
828 	if (!regs_equal(&inregs, &outregs, 0))
829 		print_serial("null test: FAIL\n");
830 	else
831 		print_serial("null test: PASS\n");
832 }
833 
834 struct {
835     char stack[500];
836     char top[];
837 } tmp_stack;
838 
839 void test_pusha_popa()
840 {
841 	struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = (unsigned long)&tmp_stack.top }, outregs;
842 
843 	MK_INSN(pusha, "pusha\n\t"
844 		       "pop %edi\n\t"
845 		       "pop %esi\n\t"
846 		       "pop %ebp\n\t"
847 		       "add $4, %esp\n\t"
848 		       "pop %ebx\n\t"
849 		       "pop %edx\n\t"
850 		       "pop %ecx\n\t"
851 		       "pop %eax\n\t"
852 		       );
853 
854 	MK_INSN(popa, "push %eax\n\t"
855 		      "push %ecx\n\t"
856 		      "push %edx\n\t"
857 		      "push %ebx\n\t"
858 		      "push %esp\n\t"
859 		      "push %ebp\n\t"
860 		      "push %esi\n\t"
861 		      "push %edi\n\t"
862 		      "popa\n\t"
863 		      );
864 
865 	exec_in_big_real_mode(&inregs, &outregs,
866 			      insn_pusha,
867 			      insn_pusha_end - insn_pusha);
868 
869 	if (!regs_equal(&inregs, &outregs, 0))
870 		print_serial("Pusha/Popa Test1: FAIL\n");
871 	else
872 		print_serial("Pusha/Popa Test1: PASS\n");
873 
874 	exec_in_big_real_mode(&inregs, &outregs,
875 			      insn_popa,
876 			      insn_popa_end - insn_popa);
877 	if (!regs_equal(&inregs, &outregs, 0))
878 		print_serial("Pusha/Popa Test2: FAIL\n");
879 	else
880 		print_serial("Pusha/Popa Test2: PASS\n");
881 }
882 
883 void test_iret()
884 {
885 	struct regs inregs = { 0 }, outregs;
886 
887 	MK_INSN(iret32, "pushf\n\t"
888 			"pushl %cs\n\t"
889 			"call 1f\n\t" /* a near call will push eip onto the stack */
890 			"jmp 2f\n\t"
891 			"1: iret\n\t"
892 			"2:\n\t"
893 		     );
894 
895 	MK_INSN(iret16, "pushfw\n\t"
896 			"pushw %cs\n\t"
897 			"callw 1f\n\t"
898 			"jmp 2f\n\t"
899 			"1: iretw\n\t"
900 			"2:\n\t");
901 
902 	MK_INSN(iret_flags32, "pushfl\n\t"
903 			      "popl %eax\n\t"
904 			      "andl $~0x2, %eax\n\t"
905 			      "orl $0xffc08028, %eax\n\t"
906 			      "pushl %eax\n\t"
907 			      "pushl %cs\n\t"
908 			      "call 1f\n\t"
909 			      "jmp 2f\n\t"
910 			      "1: iret\n\t"
911 			      "2:\n\t");
912 
913 	MK_INSN(iret_flags16, "pushfw\n\t"
914 			      "popw %ax\n\t"
915 			      "and $~0x2, %ax\n\t"
916 			      "or $0x8028, %ax\n\t"
917 			      "pushw %ax\n\t"
918 			      "pushw %cs\n\t"
919 			      "callw 1f\n\t"
920 			      "jmp 2f\n\t"
921 			      "1: iretw\n\t"
922 			      "2:\n\t");
923 
924 	exec_in_big_real_mode(&inregs, &outregs,
925 			      insn_iret32,
926 			      insn_iret32_end - insn_iret32);
927 
928 	if (!regs_equal(&inregs, &outregs, 0))
929 		print_serial("iret Test 1: FAIL\n");
930 	else
931 		print_serial("iret Test 1: PASS\n");
932 
933 	exec_in_big_real_mode(&inregs, &outregs,
934 			      insn_iret16,
935 			      insn_iret16_end - insn_iret16);
936 
937 	if (!regs_equal(&inregs, &outregs, 0))
938 		print_serial("iret Test 2: FAIL\n");
939 	else
940 		print_serial("iret Test 2: PASS\n");
941 
942 	exec_in_big_real_mode(&inregs, &outregs,
943 			      insn_iret_flags32,
944 			      insn_iret_flags32_end - insn_iret_flags32);
945 
946 	if (!regs_equal(&inregs, &outregs, R_AX))
947 		print_serial("iret Test 3: FAIL\n");
948 	else
949 		print_serial("iret Test 3: PASS\n");
950 
951 	exec_in_big_real_mode(&inregs, &outregs,
952 			      insn_iret_flags16,
953 			      insn_iret_flags16_end - insn_iret_flags16);
954 
955 	if (!regs_equal(&inregs, &outregs, R_AX))
956 		print_serial("iret Test 4: FAIL\n");
957 	else
958 		print_serial("iret Test 4: PASS\n");
959 }
960 
961 void test_int()
962 {
963 	struct regs inregs = { 0 }, outregs;
964 
965 	*(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */
966 	*(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */
967 
968 	MK_INSN(int11, "int $0x11\n\t");
969 
970 	exec_in_big_real_mode(&inregs, &outregs,
971 			      insn_int11,
972 			      insn_int11_end - insn_int11);
973 
974 	if (!regs_equal(&inregs, &outregs, 0))
975 		print_serial("int Test 1: FAIL\n");
976 	else
977 		print_serial("int Test 1: PASS\n");
978 }
979 
980 void test_imul()
981 {
982 	struct regs inregs = { 0 }, outregs;
983 
984 	MK_INSN(imul8_1, "mov $2, %al\n\t"
985 			"mov $-4, %cx\n\t"
986 			"imul %cl\n\t");
987 
988 	MK_INSN(imul16_1, "mov $2, %ax\n\t"
989 		      "mov $-4, %cx\n\t"
990 		      "imul %cx\n\t");
991 
992 	MK_INSN(imul32_1, "mov $2, %eax\n\t"
993 		       "mov $-4, %ecx\n\t"
994 		       "imul %ecx\n\t");
995 
996 	MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t"
997 			"mov $4, %cx\n\t"
998 			"imul %cl\n\t");
999 
1000 	MK_INSN(imul16_2, "mov $2, %ax\n\t"
1001 			"mov $4, %cx\n\t"
1002 			"imul %cx\n\t");
1003 
1004 	MK_INSN(imul32_2, "mov $2, %eax\n\t"
1005 			"mov $4, %ecx\n\t"
1006 			"imul %ecx\n\t");
1007 
1008 	exec_in_big_real_mode(&inregs, &outregs,
1009 			      insn_imul8_1,
1010 			      insn_imul8_1_end - insn_imul8_1);
1011 
1012 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != (u8)-8)
1013 		print_serial("imul Test 1: FAIL\n");
1014 	else
1015 		print_serial("imul Test 1: PASS\n");
1016 
1017 	exec_in_big_real_mode(&inregs, &outregs,
1018 			      insn_imul16_1,
1019 			      insn_imul16_1_end - insn_imul16_1);
1020 
1021 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-8)
1022 		print_serial("imul Test 2: FAIL\n");
1023 	else
1024 		print_serial("imul Test 2: PASS\n");
1025 
1026 	exec_in_big_real_mode(&inregs, &outregs,
1027 			      insn_imul32_1,
1028 			      insn_imul32_1_end - insn_imul32_1);
1029 
1030 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-8)
1031 		print_serial("imul Test 3: FAIL\n");
1032 	else
1033 		print_serial("imul Test 3: PASS\n");
1034 
1035 	exec_in_big_real_mode(&inregs, &outregs,
1036 			      insn_imul8_2,
1037 			      insn_imul8_2_end - insn_imul8_2);
1038 
1039 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xffff) != 8 ||
1040 	     (outregs.eax & 0xffff0000) != 0x12340000)
1041 		print_serial("imul Test 4: FAIL\n");
1042 	else
1043 		print_serial("imul Test 4: PASS\n");
1044 
1045 	exec_in_big_real_mode(&inregs, &outregs,
1046 			      insn_imul16_2,
1047 			      insn_imul16_2_end - insn_imul16_2);
1048 
1049 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8)
1050 		print_serial("imul Test 5: FAIL\n");
1051 	else
1052 		print_serial("imul Test 5: PASS\n");
1053 
1054 	exec_in_big_real_mode(&inregs, &outregs,
1055 			      insn_imul32_2,
1056 			      insn_imul32_2_end - insn_imul32_2);
1057 
1058 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8)
1059 		print_serial("imul Test 6: FAIL\n");
1060 	else
1061 		print_serial("imul Test 6: PASS\n");
1062 }
1063 
1064 void test_mul()
1065 {
1066 	struct regs inregs = { 0 }, outregs;
1067 
1068 	MK_INSN(mul8, "mov $2, %al\n\t"
1069 			"mov $4, %cx\n\t"
1070 			"imul %cl\n\t");
1071 
1072 	MK_INSN(mul16, "mov $2, %ax\n\t"
1073 			"mov $4, %cx\n\t"
1074 			"imul %cx\n\t");
1075 
1076 	MK_INSN(mul32, "mov $2, %eax\n\t"
1077 			"mov $4, %ecx\n\t"
1078 			"imul %ecx\n\t");
1079 
1080 	exec_in_big_real_mode(&inregs, &outregs,
1081 			      insn_mul8,
1082 			      insn_mul8_end - insn_mul8);
1083 
1084 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != 8)
1085 		print_serial("mul Test 1: FAIL\n");
1086 	else
1087 		print_serial("mul Test 1: PASS\n");
1088 
1089 	exec_in_big_real_mode(&inregs, &outregs,
1090 			      insn_mul16,
1091 			      insn_mul16_end - insn_mul16);
1092 
1093 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8)
1094 		print_serial("mul Test 2: FAIL\n");
1095 	else
1096 		print_serial("mul Test 2: PASS\n");
1097 
1098 	exec_in_big_real_mode(&inregs, &outregs,
1099 			      insn_mul32,
1100 			      insn_mul32_end - insn_mul32);
1101 
1102 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8)
1103 		print_serial("mul Test 3: FAIL\n");
1104 	else
1105 		print_serial("mul Test 3: PASS\n");
1106 }
1107 
1108 void test_div()
1109 {
1110 	struct regs inregs = { 0 }, outregs;
1111 
1112 	MK_INSN(div8, "mov $257, %ax\n\t"
1113 			"mov $2, %cl\n\t"
1114 			"div %cl\n\t");
1115 
1116 	MK_INSN(div16, "mov $512, %ax\n\t"
1117 			"mov $5, %cx\n\t"
1118 			"div %cx\n\t");
1119 
1120 	MK_INSN(div32, "mov $512, %eax\n\t"
1121 			"mov $5, %ecx\n\t"
1122 			"div %ecx\n\t");
1123 
1124 	exec_in_big_real_mode(&inregs, &outregs,
1125 			     insn_div8,
1126 			     insn_div8_end - insn_div8);
1127 
1128 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 384)
1129 		print_serial("div Test 1: FAIL\n");
1130 	else
1131 		print_serial("div Test 1: PASS\n");
1132 
1133 	exec_in_big_real_mode(&inregs, &outregs,
1134 			      insn_div16,
1135 			      insn_div16_end - insn_div16);
1136 
1137 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 ||
1138 	    outregs.edx != 2)
1139 		print_serial("div Test 2: FAIL\n");
1140 	else
1141 		print_serial("div Test 2: PASS\n");
1142 
1143 	exec_in_big_real_mode(&inregs, &outregs,
1144 			      insn_div32,
1145 			      insn_div32_end - insn_div32);
1146 
1147 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 ||
1148 	    outregs.edx != 2)
1149 		print_serial("div Test 3: FAIL\n");
1150 	else
1151 		print_serial("div Test 3: PASS\n");
1152 }
1153 
1154 void test_idiv()
1155 {
1156 	struct regs inregs = { 0 }, outregs;
1157 
1158 	MK_INSN(idiv8, "mov $256, %ax\n\t"
1159 			"mov $-2, %cl\n\t"
1160 			"idiv %cl\n\t");
1161 
1162 	MK_INSN(idiv16, "mov $512, %ax\n\t"
1163 			"mov $-2, %cx\n\t"
1164 			"idiv %cx\n\t");
1165 
1166 	MK_INSN(idiv32, "mov $512, %eax\n\t"
1167 			"mov $-2, %ecx\n\t"
1168 			"idiv %ecx\n\t");
1169 
1170 	exec_in_big_real_mode(&inregs, &outregs,
1171 			     insn_idiv8,
1172 			     insn_idiv8_end - insn_idiv8);
1173 
1174 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u8)-128)
1175 		print_serial("idiv Test 1: FAIL\n");
1176 	else
1177 		print_serial("idiv Test 1: PASS\n");
1178 
1179 	exec_in_big_real_mode(&inregs, &outregs,
1180 			      insn_idiv16,
1181 			      insn_idiv16_end - insn_idiv16);
1182 
1183 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-256)
1184 		print_serial("idiv Test 2: FAIL\n");
1185 	else
1186 		print_serial("idiv Test 2: PASS\n");
1187 
1188 	exec_in_big_real_mode(&inregs, &outregs,
1189 			      insn_idiv32,
1190 			      insn_idiv32_end - insn_idiv32);
1191 
1192 	if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-256)
1193 		print_serial("idiv Test 3: FAIL\n");
1194 	else
1195 		print_serial("idiv Test 3: PASS\n");
1196 }
1197 
1198 void test_cbw(void)
1199 {
1200 	struct regs inregs = { 0 }, outregs;
1201 
1202 	MK_INSN(cbw, "mov $0xFE, %eax \n\t"
1203 		     "cbw\n\t");
1204 	MK_INSN(cwde, "mov $0xFFFE, %eax \n\t"
1205 		      "cwde\n\t");
1206 
1207 	exec_in_big_real_mode(&inregs, &outregs,
1208 			      insn_cbw,
1209 			      insn_cbw_end - insn_cbw);
1210 	if (outregs.eax != 0xFFFE)
1211 		print_serial("cbw test1: FAIL\n");
1212 	else
1213 		print_serial("cbw test 1: PASS\n");
1214 
1215 	exec_in_big_real_mode(&inregs, &outregs,
1216 			      insn_cwde,
1217 			      insn_cwde_end - insn_cwde);
1218 	if (outregs.eax != 0xFFFFFFFE)
1219 		print_serial("cwde test1: FAIL\n");
1220 	else
1221 		print_serial("cwde test 1: PASS\n");
1222 }
1223 
1224 void test_loopcc(void)
1225 {
1226 	struct regs inregs = { 0 }, outregs;
1227 
1228 	MK_INSN(loop, "mov $10, %ecx\n\t"
1229 		      "1: inc %eax\n\t"
1230 		      "loop 1b\n\t");
1231 
1232 	MK_INSN(loope, "mov $10, %ecx\n\t"
1233 		       "mov $1, %eax\n\t"
1234 		       "1: dec %eax\n\t"
1235 		       "loope 1b\n\t");
1236 
1237 	MK_INSN(loopne, "mov $10, %ecx\n\t"
1238 		        "mov $5, %eax\n\t"
1239 		        "1: dec %eax\n\t"
1240 			"loopne 1b\n\t");
1241 
1242 	exec_in_big_real_mode(&inregs, &outregs,
1243 			insn_loop, insn_loop_end - insn_loop);
1244 	if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 10)
1245 		print_serial("LOOPcc short Test 1: FAIL\n");
1246 	else
1247 		print_serial("LOOPcc short Test 1: PASS\n");
1248 
1249 	exec_in_big_real_mode(&inregs, &outregs,
1250 			insn_loope, insn_loope_end - insn_loope);
1251 	if(!regs_equal(&inregs, &outregs, R_AX | R_CX) ||
1252 	   outregs.eax != -1 || outregs.ecx != 8)
1253 		print_serial("LOOPcc short Test 2: FAIL\n");
1254 	else
1255 		print_serial("LOOPcc short Test 2: PASS\n");
1256 
1257 	exec_in_big_real_mode(&inregs, &outregs,
1258 			insn_loopne, insn_loopne_end - insn_loopne);
1259 	if(!regs_equal(&inregs, &outregs, R_AX | R_CX) ||
1260 	   outregs.eax != 0 || outregs.ecx != 5)
1261 		print_serial("LOOPcc short Test 3: FAIL\n");
1262 	else
1263 		print_serial("LOOPcc short Test 3: PASS\n");
1264 }
1265 
1266 static void test_das(void)
1267 {
1268     struct regs inregs = { 0 }, outregs = { 0 };
1269     short i;
1270     static unsigned test_cases[1024] = {
1271         0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00,
1272         0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01,
1273         0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02,
1274         0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03,
1275         0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04,
1276         0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05,
1277         0x06000606, 0x8701a606, 0x56100006, 0x9711a006,
1278         0x02000707, 0x8301a707, 0x12100107, 0x9311a107,
1279         0x02000808, 0x8301a808, 0x12100208, 0x9311a208,
1280         0x06000909, 0x8701a909, 0x16100309, 0x9711a309,
1281         0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a,
1282         0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b,
1283         0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c,
1284         0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d,
1285         0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e,
1286         0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f,
1287         0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10,
1288         0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11,
1289         0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12,
1290         0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13,
1291         0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14,
1292         0x02001515, 0x8301b515, 0x16100f15, 0x9711af15,
1293         0x02001616, 0x8301b616, 0x12101016, 0x9311b016,
1294         0x06001717, 0x8701b717, 0x16101117, 0x9711b117,
1295         0x06001818, 0x8701b818, 0x16101218, 0x9711b218,
1296         0x02001919, 0x8301b919, 0x12101319, 0x9311b319,
1297         0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a,
1298         0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b,
1299         0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c,
1300         0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d,
1301         0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e,
1302         0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f,
1303         0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20,
1304         0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21,
1305         0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22,
1306         0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23,
1307         0x06002424, 0x8301c424, 0x16101e24, 0x9711be24,
1308         0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25,
1309         0x02002626, 0x8701c626, 0x12102026, 0x9711c026,
1310         0x06002727, 0x8301c727, 0x16102127, 0x9311c127,
1311         0x06002828, 0x8301c828, 0x16102228, 0x9311c228,
1312         0x02002929, 0x8701c929, 0x12102329, 0x9711c329,
1313         0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a,
1314         0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b,
1315         0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c,
1316         0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d,
1317         0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e,
1318         0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f,
1319         0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30,
1320         0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31,
1321         0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32,
1322         0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33,
1323         0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34,
1324         0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35,
1325         0x06003636, 0x8301d636, 0x16103036, 0x9311d036,
1326         0x02003737, 0x8701d737, 0x12103137, 0x9711d137,
1327         0x02003838, 0x8701d838, 0x12103238, 0x9711d238,
1328         0x06003939, 0x8301d939, 0x16103339, 0x9311d339,
1329         0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a,
1330         0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b,
1331         0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c,
1332         0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d,
1333         0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e,
1334         0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f,
1335         0x02004040, 0x8301e040, 0x16103a40, 0x9311da40,
1336         0x06004141, 0x8701e141, 0x12103b41, 0x9711db41,
1337         0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42,
1338         0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43,
1339         0x06004444, 0x8701e444, 0x12103e44, 0x9711de44,
1340         0x02004545, 0x8301e545, 0x16103f45, 0x9311df45,
1341         0x02004646, 0x8301e646, 0x12104046, 0x9311e046,
1342         0x06004747, 0x8701e747, 0x16104147, 0x9711e147,
1343         0x06004848, 0x8701e848, 0x16104248, 0x9711e248,
1344         0x02004949, 0x8301e949, 0x12104349, 0x9311e349,
1345         0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a,
1346         0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b,
1347         0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c,
1348         0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d,
1349         0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e,
1350         0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f,
1351         0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50,
1352         0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51,
1353         0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52,
1354         0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53,
1355         0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54,
1356         0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55,
1357         0x06005656, 0x8701f656, 0x16105056, 0x9711f056,
1358         0x02005757, 0x8301f757, 0x12105157, 0x9311f157,
1359         0x02005858, 0x8301f858, 0x12105258, 0x9311f258,
1360         0x06005959, 0x8701f959, 0x16105359, 0x9711f359,
1361         0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a,
1362         0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b,
1363         0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c,
1364         0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d,
1365         0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e,
1366         0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f,
1367         0x06006060, 0x47010060, 0x16105a60, 0x9711fa60,
1368         0x02006161, 0x03010161, 0x12105b61, 0x9311fb61,
1369         0x02006262, 0x03010262, 0x16105c62, 0x9711fc62,
1370         0x06006363, 0x07010363, 0x12105d63, 0x9311fd63,
1371         0x02006464, 0x03010464, 0x12105e64, 0x9311fe64,
1372         0x06006565, 0x07010565, 0x16105f65, 0x9711ff65,
1373         0x06006666, 0x07010666, 0x16106066, 0x57110066,
1374         0x02006767, 0x03010767, 0x12106167, 0x13110167,
1375         0x02006868, 0x03010868, 0x12106268, 0x13110268,
1376         0x06006969, 0x07010969, 0x16106369, 0x17110369,
1377         0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a,
1378         0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b,
1379         0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c,
1380         0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d,
1381         0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e,
1382         0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f,
1383         0x02007070, 0x03011070, 0x16106a70, 0x17110a70,
1384         0x06007171, 0x07011171, 0x12106b71, 0x13110b71,
1385         0x06007272, 0x07011272, 0x16106c72, 0x17110c72,
1386         0x02007373, 0x03011373, 0x12106d73, 0x13110d73,
1387         0x06007474, 0x07011474, 0x12106e74, 0x13110e74,
1388         0x02007575, 0x03011575, 0x16106f75, 0x17110f75,
1389         0x02007676, 0x03011676, 0x12107076, 0x13111076,
1390         0x06007777, 0x07011777, 0x16107177, 0x17111177,
1391         0x06007878, 0x07011878, 0x16107278, 0x17111278,
1392         0x02007979, 0x03011979, 0x12107379, 0x13111379,
1393         0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a,
1394         0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b,
1395         0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c,
1396         0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d,
1397         0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e,
1398         0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f,
1399         0x82008080, 0x03012080, 0x12107a80, 0x13111a80,
1400         0x86008181, 0x07012181, 0x16107b81, 0x17111b81,
1401         0x86008282, 0x07012282, 0x12107c82, 0x13111c82,
1402         0x82008383, 0x03012383, 0x16107d83, 0x17111d83,
1403         0x86008484, 0x07012484, 0x16107e84, 0x17111e84,
1404         0x82008585, 0x03012585, 0x12107f85, 0x13111f85,
1405         0x82008686, 0x03012686, 0x92108086, 0x13112086,
1406         0x86008787, 0x07012787, 0x96108187, 0x17112187,
1407         0x86008888, 0x07012888, 0x96108288, 0x17112288,
1408         0x82008989, 0x03012989, 0x92108389, 0x13112389,
1409         0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a,
1410         0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b,
1411         0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c,
1412         0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d,
1413         0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e,
1414         0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f,
1415         0x86009090, 0x07013090, 0x92108a90, 0x13112a90,
1416         0x82009191, 0x03013191, 0x96108b91, 0x17112b91,
1417         0x82009292, 0x03013292, 0x92108c92, 0x13112c92,
1418         0x86009393, 0x07013393, 0x96108d93, 0x17112d93,
1419         0x82009494, 0x03013494, 0x96108e94, 0x17112e94,
1420         0x86009595, 0x07013595, 0x92108f95, 0x13112f95,
1421         0x86009696, 0x07013696, 0x96109096, 0x17113096,
1422         0x82009797, 0x03013797, 0x92109197, 0x13113197,
1423         0x82009898, 0x03013898, 0x92109298, 0x13113298,
1424         0x86009999, 0x07013999, 0x96109399, 0x17113399,
1425         0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a,
1426         0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b,
1427         0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c,
1428         0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d,
1429         0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e,
1430         0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f,
1431         0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0,
1432         0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1,
1433         0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2,
1434         0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3,
1435         0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4,
1436         0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5,
1437         0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6,
1438         0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7,
1439         0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8,
1440         0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9,
1441         0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa,
1442         0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab,
1443         0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac,
1444         0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad,
1445         0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae,
1446         0x130049af, 0x130149af, 0x131049af, 0x131149af,
1447         0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0,
1448         0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1,
1449         0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2,
1450         0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3,
1451         0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4,
1452         0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5,
1453         0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6,
1454         0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7,
1455         0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8,
1456         0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9,
1457         0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba,
1458         0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb,
1459         0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc,
1460         0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd,
1461         0x130058be, 0x130158be, 0x131058be, 0x131158be,
1462         0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf,
1463         0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0,
1464         0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1,
1465         0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2,
1466         0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3,
1467         0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4,
1468         0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5,
1469         0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6,
1470         0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7,
1471         0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8,
1472         0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9,
1473         0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca,
1474         0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb,
1475         0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc,
1476         0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd,
1477         0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce,
1478         0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf,
1479         0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0,
1480         0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1,
1481         0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2,
1482         0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3,
1483         0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4,
1484         0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5,
1485         0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6,
1486         0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7,
1487         0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8,
1488         0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9,
1489         0x170074da, 0x170174da, 0x171074da, 0x171174da,
1490         0x130075db, 0x130175db, 0x131075db, 0x131175db,
1491         0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc,
1492         0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd,
1493         0x170078de, 0x170178de, 0x171078de, 0x171178de,
1494         0x130079df, 0x130179df, 0x131079df, 0x131179df,
1495         0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0,
1496         0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1,
1497         0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2,
1498         0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3,
1499         0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4,
1500         0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5,
1501         0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6,
1502         0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7,
1503         0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8,
1504         0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9,
1505         0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea,
1506         0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb,
1507         0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec,
1508         0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed,
1509         0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee,
1510         0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef,
1511         0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0,
1512         0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1,
1513         0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2,
1514         0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3,
1515         0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4,
1516         0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5,
1517         0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6,
1518         0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7,
1519         0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8,
1520         0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9,
1521         0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa,
1522         0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb,
1523         0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc,
1524         0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd,
1525         0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe,
1526         0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff,
1527     };
1528 
1529     MK_INSN(das, "das");
1530 
1531     for (i = 0; i < 1024; ++i) {
1532         unsigned tmp = test_cases[i];
1533         inregs.eax = tmp & 0xff;
1534         inregs.eflags = (tmp >> 16) & 0xff;
1535 	exec_in_big_real_mode(&inregs, &outregs,
1536 			      insn_das,
1537 			      insn_das_end - insn_das);
1538 
1539 	if (!regs_equal(&inregs, &outregs, R_AX)
1540             || outregs.eax != ((tmp >> 8) & 0xff)
1541             || (outregs.eflags & 0xff) != (tmp >> 24)) {
1542 		print_serial("DAS Test: FAIL\n");
1543                 return;
1544         }
1545     }
1546     print_serial("DAS Test: PASS\n");
1547 }
1548 
1549 void realmode_start(void)
1550 {
1551 	test_null();
1552 
1553 	test_shld();
1554 	test_push_pop();
1555 	test_pusha_popa();
1556 	test_mov_imm();
1557 	test_cmp_imm();
1558 	test_add_imm();
1559 	test_sub_imm();
1560 	test_xor_imm();
1561 	test_io();
1562 	test_eflags_insn();
1563 	test_jcc_short();
1564 	test_jcc_near();
1565 	/* test_call() uses short jump so call it after testing jcc */
1566 	test_call();
1567 	/* long jmp test uses call near so test it after testing call */
1568 	test_long_jmp();
1569 	test_xchg();
1570 	test_iret();
1571 	test_int();
1572 	test_imul();
1573 	test_mul();
1574 	test_div();
1575 	test_idiv();
1576 	test_loopcc();
1577 	test_cbw();
1578 	test_das();
1579 
1580 	exit(0);
1581 }
1582 
1583 unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff };
1584 
1585 struct __attribute__((packed)) {
1586 	unsigned short limit;
1587 	void *base;
1588 } r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt };
1589 
1590 asm(
1591 	".section .init \n\t"
1592 
1593 	".code32 \n\t"
1594 
1595 	"mb_magic = 0x1BADB002 \n\t"
1596 	"mb_flags = 0x0 \n\t"
1597 
1598 	"# multiboot header \n\t"
1599 	".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t"
1600 
1601 	".globl start \n\t"
1602 	".data \n\t"
1603 	". = . + 4096 \n\t"
1604 	"stacktop: \n\t"
1605 
1606 	".text \n\t"
1607 	"start: \n\t"
1608 	"lgdt r_gdt_descr \n\t"
1609 	"ljmp $8, $1f; 1: \n\t"
1610 	".code16gcc \n\t"
1611 	"mov $16, %eax \n\t"
1612 	"mov %ax, %ds \n\t"
1613 	"mov %ax, %es \n\t"
1614 	"mov %ax, %fs \n\t"
1615 	"mov %ax, %gs \n\t"
1616 	"mov %ax, %ss \n\t"
1617 	"mov %cr0, %eax \n\t"
1618 	"btc $0, %eax \n\t"
1619 	"mov %eax, %cr0 \n\t"
1620 	"ljmp $0, $realmode_entry \n\t"
1621 
1622 	"realmode_entry: \n\t"
1623 
1624 	"xor %ax, %ax \n\t"
1625 	"mov %ax, %ds \n\t"
1626 	"mov %ax, %es \n\t"
1627 	"mov %ax, %ss \n\t"
1628 	"mov %ax, %fs \n\t"
1629 	"mov %ax, %gs \n\t"
1630 	"mov $stacktop, %esp\n\t"
1631 	"ljmp $0, $realmode_start \n\t"
1632 
1633 	".code16gcc \n\t"
1634 	);
1635