17d36db35SAvi Kivity asm(".code16gcc"); 27d36db35SAvi Kivity 37d36db35SAvi Kivity typedef unsigned char u8; 47d36db35SAvi Kivity typedef unsigned short u16; 57d36db35SAvi Kivity typedef unsigned u32; 67d36db35SAvi Kivity typedef unsigned long long u64; 77d36db35SAvi Kivity 87d36db35SAvi Kivity void test_function(void); 97d36db35SAvi Kivity 107d36db35SAvi Kivity asm( 117d36db35SAvi Kivity "test_function: \n\t" 127d36db35SAvi Kivity "mov $0x1234, %eax \n\t" 137d36db35SAvi Kivity "ret" 147d36db35SAvi Kivity ); 157d36db35SAvi Kivity 167d36db35SAvi Kivity static int strlen(const char *str) 177d36db35SAvi Kivity { 187d36db35SAvi Kivity int n; 197d36db35SAvi Kivity 207d36db35SAvi Kivity for (n = 0; *str; ++str) 217d36db35SAvi Kivity ++n; 227d36db35SAvi Kivity return n; 237d36db35SAvi Kivity } 247d36db35SAvi Kivity 257d36db35SAvi Kivity static void print_serial(const char *buf) 267d36db35SAvi Kivity { 277d36db35SAvi Kivity unsigned long len = strlen(buf); 287d36db35SAvi Kivity 297d36db35SAvi Kivity asm volatile ("cld; addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1)); 307d36db35SAvi Kivity } 317d36db35SAvi Kivity 327d36db35SAvi Kivity static void exit(int code) 337d36db35SAvi Kivity { 347d36db35SAvi Kivity asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4)); 357d36db35SAvi Kivity } 367d36db35SAvi Kivity 377d36db35SAvi Kivity struct regs { 387d36db35SAvi Kivity u32 eax, ebx, ecx, edx; 397d36db35SAvi Kivity u32 esi, edi, esp, ebp; 407d36db35SAvi Kivity u32 eip, eflags; 417d36db35SAvi Kivity }; 427d36db35SAvi Kivity 437d36db35SAvi Kivity static u64 gdt[] = { 447d36db35SAvi Kivity 0, 457d36db35SAvi Kivity 0x00cf9b000000ffffull, // flat 32-bit code segment 467d36db35SAvi Kivity 0x00cf93000000ffffull, // flat 32-bit data segment 477d36db35SAvi Kivity }; 487d36db35SAvi Kivity 497d36db35SAvi Kivity static struct { 507d36db35SAvi Kivity u16 limit; 517d36db35SAvi Kivity void *base; 527d36db35SAvi Kivity } __attribute__((packed)) gdt_descr = { 537d36db35SAvi Kivity sizeof(gdt) - 1, 547d36db35SAvi Kivity gdt, 557d36db35SAvi Kivity }; 567d36db35SAvi Kivity 577d36db35SAvi Kivity static void exec_in_big_real_mode(const struct regs *inregs, 587d36db35SAvi Kivity struct regs *outregs, 597d36db35SAvi Kivity const u8 *insn, int insn_len) 607d36db35SAvi Kivity { 617d36db35SAvi Kivity unsigned long tmp; 627d36db35SAvi Kivity static struct regs save; 637d36db35SAvi Kivity int i; 647d36db35SAvi Kivity extern u8 test_insn[], test_insn_end[]; 657d36db35SAvi Kivity 667d36db35SAvi Kivity for (i = 0; i < insn_len; ++i) 677d36db35SAvi Kivity test_insn[i] = insn[i]; 687d36db35SAvi Kivity for (; i < test_insn_end - test_insn; ++i) 697d36db35SAvi Kivity test_insn[i] = 0x90; // nop 707d36db35SAvi Kivity 717d36db35SAvi Kivity save = *inregs; 727d36db35SAvi Kivity asm volatile( 737d36db35SAvi Kivity "lgdtl %[gdt_descr] \n\t" 747d36db35SAvi Kivity "mov %%cr0, %[tmp] \n\t" 757d36db35SAvi Kivity "or $1, %[tmp] \n\t" 767d36db35SAvi Kivity "mov %[tmp], %%cr0 \n\t" 777d36db35SAvi Kivity "mov %[bigseg], %%gs \n\t" 787d36db35SAvi Kivity "and $-2, %[tmp] \n\t" 797d36db35SAvi Kivity "mov %[tmp], %%cr0 \n\t" 807d36db35SAvi Kivity 8132001692SAvi Kivity "pushw %[save]+36; popfw \n\t" 827d36db35SAvi Kivity "xchg %%eax, %[save]+0 \n\t" 837d36db35SAvi Kivity "xchg %%ebx, %[save]+4 \n\t" 847d36db35SAvi Kivity "xchg %%ecx, %[save]+8 \n\t" 857d36db35SAvi Kivity "xchg %%edx, %[save]+12 \n\t" 867d36db35SAvi Kivity "xchg %%esi, %[save]+16 \n\t" 877d36db35SAvi Kivity "xchg %%edi, %[save]+20 \n\t" 887d36db35SAvi Kivity "xchg %%esp, %[save]+24 \n\t" 897d36db35SAvi Kivity "xchg %%ebp, %[save]+28 \n\t" 907d36db35SAvi Kivity 917d36db35SAvi Kivity "test_insn: . = . + 32\n\t" 927d36db35SAvi Kivity "test_insn_end: \n\t" 937d36db35SAvi Kivity 947d36db35SAvi Kivity "xchg %%eax, %[save]+0 \n\t" 957d36db35SAvi Kivity "xchg %%ebx, %[save]+4 \n\t" 967d36db35SAvi Kivity "xchg %%ecx, %[save]+8 \n\t" 977d36db35SAvi Kivity "xchg %%edx, %[save]+12 \n\t" 987d36db35SAvi Kivity "xchg %%esi, %[save]+16 \n\t" 997d36db35SAvi Kivity "xchg %%edi, %[save]+20 \n\t" 1007d36db35SAvi Kivity "xchg %%esp, %[save]+24 \n\t" 1017d36db35SAvi Kivity "xchg %%ebp, %[save]+28 \n\t" 1027d36db35SAvi Kivity 1037d36db35SAvi Kivity /* Save EFLAGS in outregs*/ 1047d36db35SAvi Kivity "pushfl \n\t" 1057d36db35SAvi Kivity "popl %[save]+36 \n\t" 1067d36db35SAvi Kivity 1077d36db35SAvi Kivity "xor %[tmp], %[tmp] \n\t" 1087d36db35SAvi Kivity "mov %[tmp], %%gs \n\t" 1097d36db35SAvi Kivity : [tmp]"=&r"(tmp), [save]"+m"(save) 1107d36db35SAvi Kivity : [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16) 1117d36db35SAvi Kivity : "cc", "memory" 1127d36db35SAvi Kivity ); 1137d36db35SAvi Kivity *outregs = save; 1147d36db35SAvi Kivity } 1157d36db35SAvi Kivity 1167d36db35SAvi Kivity #define R_AX 1 1177d36db35SAvi Kivity #define R_BX 2 1187d36db35SAvi Kivity #define R_CX 4 1197d36db35SAvi Kivity #define R_DX 8 1207d36db35SAvi Kivity #define R_SI 16 1217d36db35SAvi Kivity #define R_DI 32 1227d36db35SAvi Kivity #define R_SP 64 1237d36db35SAvi Kivity #define R_BP 128 1247d36db35SAvi Kivity 1257d36db35SAvi Kivity int regs_equal(const struct regs *r1, const struct regs *r2, int ignore) 1267d36db35SAvi Kivity { 1277d36db35SAvi Kivity const u32 *p1 = &r1->eax, *p2 = &r2->eax; // yuck 1287d36db35SAvi Kivity int i; 1297d36db35SAvi Kivity 1307d36db35SAvi Kivity for (i = 0; i < 8; ++i) 1317d36db35SAvi Kivity if (!(ignore & (1 << i)) && p1[i] != p2[i]) 1327d36db35SAvi Kivity return 0; 1337d36db35SAvi Kivity return 1; 1347d36db35SAvi Kivity } 1357d36db35SAvi Kivity 1367d36db35SAvi Kivity #define MK_INSN(name, str) \ 1377d36db35SAvi Kivity asm ( \ 1387d36db35SAvi Kivity ".text 1\n\t" \ 1397d36db35SAvi Kivity "insn_" #name ": " str " \n\t" \ 1407d36db35SAvi Kivity "insn_" #name "_end: \n\t" \ 1417d36db35SAvi Kivity ".text\n\t" \ 1427d36db35SAvi Kivity ); \ 1437d36db35SAvi Kivity extern u8 insn_##name[], insn_##name##_end[] 1447d36db35SAvi Kivity 1457d36db35SAvi Kivity void test_xchg(void) 1467d36db35SAvi Kivity { 1477d36db35SAvi Kivity struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}, outregs; 1487d36db35SAvi Kivity 1497d36db35SAvi Kivity MK_INSN(xchg_test1, "xchg %eax,%eax\n\t"); 1507d36db35SAvi Kivity MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t"); 1517d36db35SAvi Kivity MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t"); 1527d36db35SAvi Kivity MK_INSN(xchg_test4, "xchg %eax,%edx\n\t"); 1537d36db35SAvi Kivity MK_INSN(xchg_test5, "xchg %eax,%esi\n\t"); 1547d36db35SAvi Kivity MK_INSN(xchg_test6, "xchg %eax,%edi\n\t"); 1557d36db35SAvi Kivity MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t"); 1567d36db35SAvi Kivity MK_INSN(xchg_test8, "xchg %eax,%esp\n\t"); 1577d36db35SAvi Kivity 1587d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1597d36db35SAvi Kivity insn_xchg_test1, 1607d36db35SAvi Kivity insn_xchg_test1_end - insn_xchg_test1); 1617d36db35SAvi Kivity 1627d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 1637d36db35SAvi Kivity print_serial("xchg test 1: FAIL\n"); 1647d36db35SAvi Kivity else 1657d36db35SAvi Kivity print_serial("xchg test 1: PASS\n"); 1667d36db35SAvi Kivity 1677d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1687d36db35SAvi Kivity insn_xchg_test2, 1697d36db35SAvi Kivity insn_xchg_test2_end - insn_xchg_test2); 1707d36db35SAvi Kivity 1717d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_BX) || 1727d36db35SAvi Kivity outregs.eax != inregs.ebx || 1737d36db35SAvi Kivity outregs.ebx != inregs.eax) 1747d36db35SAvi Kivity print_serial("xchg test 2: FAIL\n"); 1757d36db35SAvi Kivity else 1767d36db35SAvi Kivity print_serial("xchg test 2: PASS\n"); 1777d36db35SAvi Kivity 1787d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1797d36db35SAvi Kivity insn_xchg_test3, 1807d36db35SAvi Kivity insn_xchg_test3_end - insn_xchg_test3); 1817d36db35SAvi Kivity 1827d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_CX) || 1837d36db35SAvi Kivity outregs.eax != inregs.ecx || 1847d36db35SAvi Kivity outregs.ecx != inregs.eax) 1857d36db35SAvi Kivity print_serial("xchg test 3: FAIL\n"); 1867d36db35SAvi Kivity else 1877d36db35SAvi Kivity print_serial("xchg test 3: PASS\n"); 1887d36db35SAvi Kivity 1897d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1907d36db35SAvi Kivity insn_xchg_test4, 1917d36db35SAvi Kivity insn_xchg_test4_end - insn_xchg_test4); 1927d36db35SAvi Kivity 1937d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || 1947d36db35SAvi Kivity outregs.eax != inregs.edx || 1957d36db35SAvi Kivity outregs.edx != inregs.eax) 1967d36db35SAvi Kivity print_serial("xchg test 4: FAIL\n"); 1977d36db35SAvi Kivity else 1987d36db35SAvi Kivity print_serial("xchg test 4: PASS\n"); 1997d36db35SAvi Kivity 2007d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2017d36db35SAvi Kivity insn_xchg_test5, 2027d36db35SAvi Kivity insn_xchg_test5_end - insn_xchg_test5); 2037d36db35SAvi Kivity 2047d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_SI) || 2057d36db35SAvi Kivity outregs.eax != inregs.esi || 2067d36db35SAvi Kivity outregs.esi != inregs.eax) 2077d36db35SAvi Kivity print_serial("xchg test 5: FAIL\n"); 2087d36db35SAvi Kivity else 2097d36db35SAvi Kivity print_serial("xchg test 5: PASS\n"); 2107d36db35SAvi Kivity 2117d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2127d36db35SAvi Kivity insn_xchg_test6, 2137d36db35SAvi Kivity insn_xchg_test6_end - insn_xchg_test6); 2147d36db35SAvi Kivity 2157d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_DI) || 2167d36db35SAvi Kivity outregs.eax != inregs.edi || 2177d36db35SAvi Kivity outregs.edi != inregs.eax) 2187d36db35SAvi Kivity print_serial("xchg test 6: FAIL\n"); 2197d36db35SAvi Kivity else 2207d36db35SAvi Kivity print_serial("xchg test 6: PASS\n"); 2217d36db35SAvi Kivity 2227d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2237d36db35SAvi Kivity insn_xchg_test7, 2247d36db35SAvi Kivity insn_xchg_test7_end - insn_xchg_test7); 2257d36db35SAvi Kivity 2267d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_BP) || 2277d36db35SAvi Kivity outregs.eax != inregs.ebp || 2287d36db35SAvi Kivity outregs.ebp != inregs.eax) 2297d36db35SAvi Kivity print_serial("xchg test 7: FAIL\n"); 2307d36db35SAvi Kivity else 2317d36db35SAvi Kivity print_serial("xchg test 7: PASS\n"); 2327d36db35SAvi Kivity 2337d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2347d36db35SAvi Kivity insn_xchg_test8, 2357d36db35SAvi Kivity insn_xchg_test8_end - insn_xchg_test8); 2367d36db35SAvi Kivity 2377d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_SP) || 2387d36db35SAvi Kivity outregs.eax != inregs.esp || 2397d36db35SAvi Kivity outregs.esp != inregs.eax) 2407d36db35SAvi Kivity print_serial("xchg test 8: FAIL\n"); 2417d36db35SAvi Kivity else 2427d36db35SAvi Kivity print_serial("xchg test 8: PASS\n"); 2437d36db35SAvi Kivity } 2447d36db35SAvi Kivity 2457d36db35SAvi Kivity void test_shld(void) 2467d36db35SAvi Kivity { 2477d36db35SAvi Kivity struct regs inregs = { .eax = 0xbe, .edx = 0xef000000 }, outregs; 2487d36db35SAvi Kivity MK_INSN(shld_test, "shld $8,%edx,%eax\n\t"); 2497d36db35SAvi Kivity 2507d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2517d36db35SAvi Kivity insn_shld_test, 2527d36db35SAvi Kivity insn_shld_test_end - insn_shld_test); 2537d36db35SAvi Kivity if (outregs.eax != 0xbeef) 2547d36db35SAvi Kivity print_serial("shld: FAIL\n"); 2557d36db35SAvi Kivity else 2567d36db35SAvi Kivity print_serial("shld: PASS\n"); 2577d36db35SAvi Kivity } 2587d36db35SAvi Kivity 2597d36db35SAvi Kivity void test_mov_imm(void) 2607d36db35SAvi Kivity { 2617d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 2627d36db35SAvi Kivity MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax"); 2637d36db35SAvi Kivity MK_INSN(mov_r16_imm_1, "mov $1234, %ax"); 2647d36db35SAvi Kivity MK_INSN(mov_r8_imm_1, "mov $0x12, %ah"); 2657d36db35SAvi Kivity MK_INSN(mov_r8_imm_2, "mov $0x34, %al"); 2667d36db35SAvi Kivity MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t"); 2677d36db35SAvi Kivity 2687d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2697d36db35SAvi Kivity insn_mov_r16_imm_1, 2707d36db35SAvi Kivity insn_mov_r16_imm_1_end - insn_mov_r16_imm_1); 2717d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234) 2727d36db35SAvi Kivity print_serial("mov test 1: FAIL\n"); 2737d36db35SAvi Kivity else 2747d36db35SAvi Kivity print_serial("mov test 1: PASS\n"); 2757d36db35SAvi Kivity 2767d36db35SAvi Kivity /* test mov $imm, %eax */ 2777d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2787d36db35SAvi Kivity insn_mov_r32_imm_1, 2797d36db35SAvi Kivity insn_mov_r32_imm_1_end - insn_mov_r32_imm_1); 2807d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567890) 2817d36db35SAvi Kivity print_serial("mov test 2: FAIL\n"); 2827d36db35SAvi Kivity else 2837d36db35SAvi Kivity print_serial("mov test 2: PASS\n"); 2847d36db35SAvi Kivity 2857d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 2867d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2877d36db35SAvi Kivity insn_mov_r8_imm_1, 2887d36db35SAvi Kivity insn_mov_r8_imm_1_end - insn_mov_r8_imm_1); 2897d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1200) 2907d36db35SAvi Kivity print_serial("mov test 3: FAIL\n"); 2917d36db35SAvi Kivity else 2927d36db35SAvi Kivity print_serial("mov test 3: PASS\n"); 2937d36db35SAvi Kivity 2947d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2957d36db35SAvi Kivity insn_mov_r8_imm_2, 2967d36db35SAvi Kivity insn_mov_r8_imm_2_end - insn_mov_r8_imm_2); 2977d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x34) 2987d36db35SAvi Kivity print_serial("mov test 4: FAIL\n"); 2997d36db35SAvi Kivity else 3007d36db35SAvi Kivity print_serial("mov test 4: PASS\n"); 3017d36db35SAvi Kivity 3027d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3037d36db35SAvi Kivity insn_mov_r8_imm_3, 3047d36db35SAvi Kivity insn_mov_r8_imm_3_end - insn_mov_r8_imm_3); 3057d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 3067d36db35SAvi Kivity print_serial("mov test 5: FAIL\n"); 3077d36db35SAvi Kivity else 3087d36db35SAvi Kivity print_serial("mov test 5: PASS\n"); 3097d36db35SAvi Kivity } 3107d36db35SAvi Kivity 3117d36db35SAvi Kivity void test_sub_imm(void) 3127d36db35SAvi Kivity { 3137d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 3147d36db35SAvi Kivity MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t"); 3157d36db35SAvi Kivity MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t"); 3167d36db35SAvi Kivity MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t"); 3177d36db35SAvi Kivity MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t"); 3187d36db35SAvi Kivity 3197d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3207d36db35SAvi Kivity insn_sub_r16_imm_1, 3217d36db35SAvi Kivity insn_sub_r16_imm_1_end - insn_sub_r16_imm_1); 3227d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1224) 3237d36db35SAvi Kivity print_serial("sub test 1: FAIL\n"); 3247d36db35SAvi Kivity else 3257d36db35SAvi Kivity print_serial("sub test 1: PASS\n"); 3267d36db35SAvi Kivity 3277d36db35SAvi Kivity /* test mov $imm, %eax */ 3287d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3297d36db35SAvi Kivity insn_sub_r32_imm_1, 3307d36db35SAvi Kivity insn_sub_r32_imm_1_end - insn_sub_r32_imm_1); 3317d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567880) 3327d36db35SAvi Kivity print_serial("sub test 2: FAIL\n"); 3337d36db35SAvi Kivity else 3347d36db35SAvi Kivity print_serial("sub test 2: PASS\n"); 3357d36db35SAvi Kivity 3367d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 3377d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3387d36db35SAvi Kivity insn_sub_r8_imm_1, 3397d36db35SAvi Kivity insn_sub_r8_imm_1_end - insn_sub_r8_imm_1); 3407d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x0200) 3417d36db35SAvi Kivity print_serial("sub test 3: FAIL\n"); 3427d36db35SAvi Kivity else 3437d36db35SAvi Kivity print_serial("sub test 3: PASS\n"); 3447d36db35SAvi Kivity 3457d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3467d36db35SAvi Kivity insn_sub_r8_imm_2, 3477d36db35SAvi Kivity insn_sub_r8_imm_2_end - insn_sub_r8_imm_2); 3487d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x24) 3497d36db35SAvi Kivity print_serial("sub test 4: FAIL\n"); 3507d36db35SAvi Kivity else 3517d36db35SAvi Kivity print_serial("sub test 4: PASS\n"); 3527d36db35SAvi Kivity } 3537d36db35SAvi Kivity 3547d36db35SAvi Kivity 3557d36db35SAvi Kivity void test_xor_imm(void) 3567d36db35SAvi Kivity { 3577d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 3587d36db35SAvi Kivity MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t"); 3597d36db35SAvi Kivity MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t"); 3607d36db35SAvi Kivity MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t"); 3617d36db35SAvi Kivity MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t"); 3627d36db35SAvi Kivity 3637d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3647d36db35SAvi Kivity insn_xor_r16_imm_1, 3657d36db35SAvi Kivity insn_xor_r16_imm_1_end - insn_xor_r16_imm_1); 3667d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 3677d36db35SAvi Kivity print_serial("xor test 1: FAIL\n"); 3687d36db35SAvi Kivity else 3697d36db35SAvi Kivity print_serial("xor test 1: PASS\n"); 3707d36db35SAvi Kivity 3717d36db35SAvi Kivity /* test mov $imm, %eax */ 3727d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3737d36db35SAvi Kivity insn_xor_r32_imm_1, 3747d36db35SAvi Kivity insn_xor_r32_imm_1_end - insn_xor_r32_imm_1); 3757d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 3767d36db35SAvi Kivity print_serial("xor test 2: FAIL\n"); 3777d36db35SAvi Kivity else 3787d36db35SAvi Kivity print_serial("xor test 2: PASS\n"); 3797d36db35SAvi Kivity 3807d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 3817d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3827d36db35SAvi Kivity insn_xor_r8_imm_1, 3837d36db35SAvi Kivity insn_xor_r8_imm_1_end - insn_xor_r8_imm_1); 3847d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 3857d36db35SAvi Kivity print_serial("xor test 3: FAIL\n"); 3867d36db35SAvi Kivity else 3877d36db35SAvi Kivity print_serial("xor test 3: PASS\n"); 3887d36db35SAvi Kivity 3897d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3907d36db35SAvi Kivity insn_xor_r8_imm_2, 3917d36db35SAvi Kivity insn_xor_r8_imm_2_end - insn_xor_r8_imm_2); 3927d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 3937d36db35SAvi Kivity print_serial("xor test 4: FAIL\n"); 3947d36db35SAvi Kivity else 3957d36db35SAvi Kivity print_serial("xor test 4: PASS\n"); 3967d36db35SAvi Kivity } 3977d36db35SAvi Kivity 3987d36db35SAvi Kivity void test_cmp_imm(void) 3997d36db35SAvi Kivity { 4007d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 4017d36db35SAvi Kivity MK_INSN(cmp_test1, "mov $0x34, %al\n\t" 4027d36db35SAvi Kivity "cmp $0x34, %al\n\t"); 4037d36db35SAvi Kivity MK_INSN(cmp_test2, "mov $0x34, %al\n\t" 4047d36db35SAvi Kivity "cmp $0x39, %al\n\t"); 4057d36db35SAvi Kivity MK_INSN(cmp_test3, "mov $0x34, %al\n\t" 4067d36db35SAvi Kivity "cmp $0x24, %al\n\t"); 4077d36db35SAvi Kivity 4087d36db35SAvi Kivity /* test cmp imm8 with AL */ 4097d36db35SAvi Kivity /* ZF: (bit 6) Zero Flag becomes 1 if an operation results 4107d36db35SAvi Kivity * in a 0 writeback, or 0 register 4117d36db35SAvi Kivity */ 4127d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4137d36db35SAvi Kivity insn_cmp_test1, 4147d36db35SAvi Kivity insn_cmp_test1_end - insn_cmp_test1); 4157d36db35SAvi Kivity if ((outregs.eflags & (1<<6)) != (1<<6)) 4167d36db35SAvi Kivity print_serial("cmp test 1: FAIL\n"); 4177d36db35SAvi Kivity else 4187d36db35SAvi Kivity print_serial("cmp test 1: PASS\n"); 4197d36db35SAvi Kivity 4207d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4217d36db35SAvi Kivity insn_cmp_test2, 4227d36db35SAvi Kivity insn_cmp_test2_end - insn_cmp_test2); 4237d36db35SAvi Kivity if ((outregs.eflags & (1<<6)) != 0) 4247d36db35SAvi Kivity print_serial("cmp test 2: FAIL\n"); 4257d36db35SAvi Kivity else 4267d36db35SAvi Kivity print_serial("cmp test 2: PASS\n"); 4277d36db35SAvi Kivity 4287d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4297d36db35SAvi Kivity insn_cmp_test3, 4307d36db35SAvi Kivity insn_cmp_test3_end - insn_cmp_test3); 4317d36db35SAvi Kivity if ((outregs.eflags & (1<<6)) != 0) 4327d36db35SAvi Kivity print_serial("cmp test 3: FAIL\n"); 4337d36db35SAvi Kivity else 4347d36db35SAvi Kivity print_serial("cmp test 3: PASS\n"); 4357d36db35SAvi Kivity } 4367d36db35SAvi Kivity 4377d36db35SAvi Kivity void test_add_imm(void) 4387d36db35SAvi Kivity { 4397d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 4407d36db35SAvi Kivity MK_INSN(add_test1, "mov $0x43211234, %eax \n\t" 4417d36db35SAvi Kivity "add $0x12344321, %eax \n\t"); 4427d36db35SAvi Kivity MK_INSN(add_test2, "mov $0x12, %eax \n\t" 4437d36db35SAvi Kivity "add $0x21, %al\n\t"); 4447d36db35SAvi Kivity 4457d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4467d36db35SAvi Kivity insn_add_test1, 4477d36db35SAvi Kivity insn_add_test1_end - insn_add_test1); 4487d36db35SAvi Kivity if (outregs.eax != 0x55555555) 4497d36db35SAvi Kivity print_serial("add test 1: FAIL\n"); 4507d36db35SAvi Kivity else 4517d36db35SAvi Kivity print_serial("add test 1: PASS\n"); 4527d36db35SAvi Kivity 4537d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4547d36db35SAvi Kivity insn_add_test2, 4557d36db35SAvi Kivity insn_add_test2_end - insn_add_test2); 4567d36db35SAvi Kivity if (outregs.eax != 0x33) 4577d36db35SAvi Kivity print_serial("add test 2: FAIL\n"); 4587d36db35SAvi Kivity else 4597d36db35SAvi Kivity print_serial("add test 2: PASS\n"); 4607d36db35SAvi Kivity } 4617d36db35SAvi Kivity 4627d36db35SAvi Kivity void test_eflags_insn(void) 4637d36db35SAvi Kivity { 4647d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 4657d36db35SAvi Kivity MK_INSN(clc, "clc"); 466b3261e48SMohammed Gamal MK_INSN(stc, "stc"); 4677d36db35SAvi Kivity MK_INSN(cli, "cli"); 4687d36db35SAvi Kivity MK_INSN(sti, "sti"); 4697d36db35SAvi Kivity MK_INSN(cld, "cld"); 4707d36db35SAvi Kivity MK_INSN(std, "std"); 4717d36db35SAvi Kivity 4727d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4737d36db35SAvi Kivity insn_clc, 4747d36db35SAvi Kivity insn_clc_end - insn_clc); 4757d36db35SAvi Kivity if (outregs.eflags & 1) 4767d36db35SAvi Kivity print_serial("clc test: FAIL\n"); 4777d36db35SAvi Kivity else 4787d36db35SAvi Kivity print_serial("clc test: PASS\n"); 4797d36db35SAvi Kivity 4807d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 481b3261e48SMohammed Gamal insn_stc, 482b3261e48SMohammed Gamal insn_stc_end - insn_stc); 483b3261e48SMohammed Gamal if (!(outregs.eflags & 1)) 484b3261e48SMohammed Gamal print_serial("stc test: FAIL\n"); 485b3261e48SMohammed Gamal else 486b3261e48SMohammed Gamal print_serial("stc test: PASS\n"); 487b3261e48SMohammed Gamal 488b3261e48SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 4897d36db35SAvi Kivity insn_cli, 4907d36db35SAvi Kivity insn_cli_end - insn_cli); 4917d36db35SAvi Kivity if (outregs.eflags & (1 << 9)) 4927d36db35SAvi Kivity print_serial("cli test: FAIL\n"); 4937d36db35SAvi Kivity else 4947d36db35SAvi Kivity print_serial("cli test: PASS\n"); 4957d36db35SAvi Kivity 4967d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4977d36db35SAvi Kivity insn_sti, 4987d36db35SAvi Kivity insn_sti_end - insn_sti); 4997d36db35SAvi Kivity if (!(outregs.eflags & (1 << 9))) 5007d36db35SAvi Kivity print_serial("sti test: FAIL\n"); 5017d36db35SAvi Kivity else 5027d36db35SAvi Kivity print_serial("sti test: PASS\n"); 5037d36db35SAvi Kivity 5047d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5057d36db35SAvi Kivity insn_cld, 5067d36db35SAvi Kivity insn_cld_end - insn_cld); 5077d36db35SAvi Kivity if (outregs.eflags & (1 << 10)) 5087d36db35SAvi Kivity print_serial("cld test: FAIL\n"); 5097d36db35SAvi Kivity else 5107d36db35SAvi Kivity print_serial("cld test: PASS\n"); 5117d36db35SAvi Kivity 5127d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5137d36db35SAvi Kivity insn_std, 5147d36db35SAvi Kivity insn_std_end - insn_std); 5157d36db35SAvi Kivity if (!(outregs.eflags & (1 << 10))) 5167d36db35SAvi Kivity print_serial("std test: FAIL\n"); 5177d36db35SAvi Kivity else 5187d36db35SAvi Kivity print_serial("std test: PASS\n"); 5197d36db35SAvi Kivity } 5207d36db35SAvi Kivity 5217d36db35SAvi Kivity void test_io(void) 5227d36db35SAvi Kivity { 5237d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 5247d36db35SAvi Kivity MK_INSN(io_test1, "mov $0xff, %al \n\t" 5257d36db35SAvi Kivity "out %al, $0xe0 \n\t" 5267d36db35SAvi Kivity "mov $0x00, %al \n\t" 5277d36db35SAvi Kivity "in $0xe0, %al \n\t"); 5287d36db35SAvi Kivity MK_INSN(io_test2, "mov $0xffff, %ax \n\t" 5297d36db35SAvi Kivity "out %ax, $0xe0 \n\t" 5307d36db35SAvi Kivity "mov $0x0000, %ax \n\t" 5317d36db35SAvi Kivity "in $0xe0, %ax \n\t"); 5327d36db35SAvi Kivity MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t" 5337d36db35SAvi Kivity "out %eax, $0xe0 \n\t" 5347d36db35SAvi Kivity "mov $0x000000, %eax \n\t" 5357d36db35SAvi Kivity "in $0xe0, %eax \n\t"); 5367d36db35SAvi Kivity MK_INSN(io_test4, "mov $0xe0, %dx \n\t" 5377d36db35SAvi Kivity "mov $0xff, %al \n\t" 5387d36db35SAvi Kivity "out %al, %dx \n\t" 5397d36db35SAvi Kivity "mov $0x00, %al \n\t" 5407d36db35SAvi Kivity "in %dx, %al \n\t"); 5417d36db35SAvi Kivity MK_INSN(io_test5, "mov $0xe0, %dx \n\t" 5427d36db35SAvi Kivity "mov $0xffff, %ax \n\t" 5437d36db35SAvi Kivity "out %ax, %dx \n\t" 5447d36db35SAvi Kivity "mov $0x0000, %ax \n\t" 5457d36db35SAvi Kivity "in %dx, %ax \n\t"); 5467d36db35SAvi Kivity MK_INSN(io_test6, "mov $0xe0, %dx \n\t" 5477d36db35SAvi Kivity "mov $0xffffffff, %eax \n\t" 5487d36db35SAvi Kivity "out %eax, %dx \n\t" 5497d36db35SAvi Kivity "mov $0x00000000, %eax \n\t" 5507d36db35SAvi Kivity "in %dx, %eax \n\t"); 5517d36db35SAvi Kivity 5527d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5537d36db35SAvi Kivity insn_io_test1, 5547d36db35SAvi Kivity insn_io_test1_end - insn_io_test1); 5557d36db35SAvi Kivity 5567d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xff) 5577d36db35SAvi Kivity print_serial("I/O test 1: FAIL\n"); 5587d36db35SAvi Kivity else 5597d36db35SAvi Kivity print_serial("I/O test 1: PASS\n"); 5607d36db35SAvi Kivity 5617d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5627d36db35SAvi Kivity insn_io_test2, 5637d36db35SAvi Kivity insn_io_test2_end - insn_io_test2); 5647d36db35SAvi Kivity 5657d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffff) 5667d36db35SAvi Kivity print_serial("I/O test 2: FAIL\n"); 5677d36db35SAvi Kivity else 5687d36db35SAvi Kivity print_serial("I/O test 2: PASS\n"); 5697d36db35SAvi Kivity 5707d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5717d36db35SAvi Kivity insn_io_test3, 5727d36db35SAvi Kivity insn_io_test3_end - insn_io_test3); 5737d36db35SAvi Kivity 5747d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffffffff) 5757d36db35SAvi Kivity print_serial("I/O test 3: FAIL\n"); 5767d36db35SAvi Kivity else 5777d36db35SAvi Kivity print_serial("I/O test 3: PASS\n"); 5787d36db35SAvi Kivity 5797d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5807d36db35SAvi Kivity insn_io_test4, 5817d36db35SAvi Kivity insn_io_test4_end - insn_io_test4); 5827d36db35SAvi Kivity 5837d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xff) 5847d36db35SAvi Kivity print_serial("I/O test 4: FAIL\n"); 5857d36db35SAvi Kivity else 5867d36db35SAvi Kivity print_serial("I/O test 4: PASS\n"); 5877d36db35SAvi Kivity 5887d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5897d36db35SAvi Kivity insn_io_test5, 5907d36db35SAvi Kivity insn_io_test5_end - insn_io_test5); 5917d36db35SAvi Kivity 5927d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffff) 5937d36db35SAvi Kivity print_serial("I/O test 5: FAIL\n"); 5947d36db35SAvi Kivity else 5957d36db35SAvi Kivity print_serial("I/O test 5: PASS\n"); 5967d36db35SAvi Kivity 5977d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5987d36db35SAvi Kivity insn_io_test6, 5997d36db35SAvi Kivity insn_io_test6_end - insn_io_test6); 6007d36db35SAvi Kivity 6017d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffffffff) 6027d36db35SAvi Kivity print_serial("I/O test 6: FAIL\n"); 6037d36db35SAvi Kivity else 6047d36db35SAvi Kivity print_serial("I/O test 6: PASS\n"); 6057d36db35SAvi Kivity } 6067d36db35SAvi Kivity 607c0b7268dSAvi Kivity asm ("retf: lretw"); 608c0b7268dSAvi Kivity extern void retf(); 609c0b7268dSAvi Kivity 6107d36db35SAvi Kivity void test_call(void) 6117d36db35SAvi Kivity { 6127d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 6137d36db35SAvi Kivity u32 esp[16]; 614c0b7268dSAvi Kivity u32 addr; 6157d36db35SAvi Kivity 6167d36db35SAvi Kivity inregs.esp = (u32)esp; 6177d36db35SAvi Kivity 6187d36db35SAvi Kivity MK_INSN(call1, "mov $test_function, %eax \n\t" 6197d36db35SAvi Kivity "call *%eax\n\t"); 6207d36db35SAvi Kivity MK_INSN(call_near1, "jmp 2f\n\t" 6217d36db35SAvi Kivity "1: mov $0x1234, %eax\n\t" 6227d36db35SAvi Kivity "ret\n\t" 6237d36db35SAvi Kivity "2: call 1b\t"); 6247d36db35SAvi Kivity MK_INSN(call_near2, "call 1f\n\t" 6257d36db35SAvi Kivity "jmp 2f\n\t" 6267d36db35SAvi Kivity "1: mov $0x1234, %eax\n\t" 6277d36db35SAvi Kivity "ret\n\t" 6287d36db35SAvi Kivity "2:\t"); 629c0b7268dSAvi Kivity MK_INSN(call_far1, "lcallw *(%ebx)\n\t"); 630*c6061817SAvi Kivity MK_INSN(ret_imm, "sub $10, %sp; jmp 2f; 1: retw $10; 2: callw 1b"); 6317d36db35SAvi Kivity 6327d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6337d36db35SAvi Kivity insn_call1, 6347d36db35SAvi Kivity insn_call1_end - insn_call1); 6357d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 6367d36db35SAvi Kivity print_serial("Call Test 1: FAIL\n"); 6377d36db35SAvi Kivity else 6387d36db35SAvi Kivity print_serial("Call Test 1: PASS\n"); 6397d36db35SAvi Kivity 6407d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6417d36db35SAvi Kivity insn_call_near1, insn_call_near1_end - insn_call_near1); 6427d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 6437d36db35SAvi Kivity print_serial("Call near Test 1: FAIL\n"); 6447d36db35SAvi Kivity else 6457d36db35SAvi Kivity print_serial("Call near Test 1: PASS\n"); 6467d36db35SAvi Kivity 6477d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6487d36db35SAvi Kivity insn_call_near2, insn_call_near2_end - insn_call_near2); 6497d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 6507d36db35SAvi Kivity print_serial("Call near Test 2: FAIL\n"); 6517d36db35SAvi Kivity else 6527d36db35SAvi Kivity print_serial("Call near Test 2: PASS\n"); 653c0b7268dSAvi Kivity 654c0b7268dSAvi Kivity addr = (((unsigned)retf >> 4) << 16) | ((unsigned)retf & 0x0f); 655c0b7268dSAvi Kivity inregs.ebx = (unsigned)&addr; 656c0b7268dSAvi Kivity exec_in_big_real_mode(&inregs, &outregs, insn_call_far1, 657c0b7268dSAvi Kivity insn_call_far1_end - insn_call_far1); 658c0b7268dSAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 659c0b7268dSAvi Kivity print_serial("Call far Test 1: FAIL\n"); 660c0b7268dSAvi Kivity else 661c0b7268dSAvi Kivity print_serial("Call far Test 1: PASS\n"); 662*c6061817SAvi Kivity 663*c6061817SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, insn_ret_imm, 664*c6061817SAvi Kivity insn_ret_imm_end - insn_ret_imm); 665*c6061817SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 666*c6061817SAvi Kivity print_serial("ret imm Test 1: FAIL\n"); 667*c6061817SAvi Kivity else 668*c6061817SAvi Kivity print_serial("ret imm Test 1: PASS\n"); 6697d36db35SAvi Kivity } 6707d36db35SAvi Kivity 6717d36db35SAvi Kivity void test_jcc_short(void) 6727d36db35SAvi Kivity { 6737d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 6747d36db35SAvi Kivity MK_INSN(jnz_short1, "jnz 1f\n\t" 6757d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6767d36db35SAvi Kivity "1:\n\t"); 6777d36db35SAvi Kivity MK_INSN(jnz_short2, "1:\n\t" 6787d36db35SAvi Kivity "cmp $0x1234, %eax\n\t" 6797d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6807d36db35SAvi Kivity "jnz 1b\n\t"); 6817d36db35SAvi Kivity MK_INSN(jmp_short1, "jmp 1f\n\t" 6827d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6837d36db35SAvi Kivity "1:\n\t"); 6847d36db35SAvi Kivity 6857d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6867d36db35SAvi Kivity insn_jnz_short1, insn_jnz_short1_end - insn_jnz_short1); 6877d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, 0)) 6887d36db35SAvi Kivity print_serial("JNZ short Test 1: FAIL\n"); 6897d36db35SAvi Kivity else 6907d36db35SAvi Kivity print_serial("JNZ short Test 1: PASS\n"); 6917d36db35SAvi Kivity 6927d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6937d36db35SAvi Kivity insn_jnz_short2, insn_jnz_short2_end - insn_jnz_short2); 6947d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6))) 6957d36db35SAvi Kivity print_serial("JNZ short Test 2: FAIL\n"); 6967d36db35SAvi Kivity else 6977d36db35SAvi Kivity print_serial("JNZ short Test 2: PASS\n"); 6987d36db35SAvi Kivity 6997d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7007d36db35SAvi Kivity insn_jmp_short1, insn_jmp_short1_end - insn_jmp_short1); 7017d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, 0)) 7027d36db35SAvi Kivity print_serial("JMP short Test 1: FAIL\n"); 7037d36db35SAvi Kivity else 7047d36db35SAvi Kivity print_serial("JMP short Test 1: PASS\n"); 7057d36db35SAvi Kivity } 7067d36db35SAvi Kivity 7077d36db35SAvi Kivity void test_jcc_near(void) 7087d36db35SAvi Kivity { 7097d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 7107d36db35SAvi Kivity /* encode near jmp manually. gas will not do it if offsets < 127 byte */ 7117d36db35SAvi Kivity MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t" 7127d36db35SAvi Kivity "mov $0x1234, %eax\n\t"); 7137d36db35SAvi Kivity MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t" 7147d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 7157d36db35SAvi Kivity ".byte 0x0f, 0x85, 0xf0, 0xff\n\t"); 7167d36db35SAvi Kivity MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t" 7177d36db35SAvi Kivity "mov $0x1234, %eax\n\t"); 7187d36db35SAvi Kivity 7197d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7207d36db35SAvi Kivity insn_jnz_near1, insn_jnz_near1_end - insn_jnz_near1); 7217d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, 0)) 7227d36db35SAvi Kivity print_serial("JNZ near Test 1: FAIL\n"); 7237d36db35SAvi Kivity else 7247d36db35SAvi Kivity print_serial("JNZ near Test 1: PASS\n"); 7257d36db35SAvi Kivity 7267d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7277d36db35SAvi Kivity insn_jnz_near2, insn_jnz_near2_end - insn_jnz_near2); 7287d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6))) 7297d36db35SAvi Kivity print_serial("JNZ near Test 2: FAIL\n"); 7307d36db35SAvi Kivity else 7317d36db35SAvi Kivity print_serial("JNZ near Test 2: PASS\n"); 7327d36db35SAvi Kivity 7337d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7347d36db35SAvi Kivity insn_jmp_near1, insn_jmp_near1_end - insn_jmp_near1); 7357d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, 0)) 7367d36db35SAvi Kivity print_serial("JMP near Test 1: FAIL\n"); 7377d36db35SAvi Kivity else 7387d36db35SAvi Kivity print_serial("JMP near Test 1: PASS\n"); 7397d36db35SAvi Kivity } 7407d36db35SAvi Kivity 7417d36db35SAvi Kivity void test_long_jmp() 7427d36db35SAvi Kivity { 7437d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 7447d36db35SAvi Kivity u32 esp[16]; 7457d36db35SAvi Kivity 7467d36db35SAvi Kivity inregs.esp = (u32)esp; 7477d36db35SAvi Kivity MK_INSN(long_jmp, "call 1f\n\t" 7487d36db35SAvi Kivity "jmp 2f\n\t" 7497d36db35SAvi Kivity "1: jmp $0, $test_function\n\t" 7507d36db35SAvi Kivity "2:\n\t"); 7517d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7527d36db35SAvi Kivity insn_long_jmp, 7537d36db35SAvi Kivity insn_long_jmp_end - insn_long_jmp); 7547d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 7557d36db35SAvi Kivity print_serial("Long JMP Test: FAIL\n"); 7567d36db35SAvi Kivity else 7577d36db35SAvi Kivity print_serial("Long JMP Test: PASS\n"); 7587d36db35SAvi Kivity } 759fa74f8a6SMohammed Gamal 7607d36db35SAvi Kivity void test_push_pop() 7617d36db35SAvi Kivity { 7627d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 7637d36db35SAvi Kivity MK_INSN(push32, "mov $0x12345678, %eax\n\t" 7647d36db35SAvi Kivity "push %eax\n\t" 7657d36db35SAvi Kivity "pop %ebx\n\t"); 7667d36db35SAvi Kivity MK_INSN(push16, "mov $0x1234, %ax\n\t" 7677d36db35SAvi Kivity "push %ax\n\t" 7687d36db35SAvi Kivity "pop %bx\n\t"); 7697d36db35SAvi Kivity 7707d36db35SAvi Kivity MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten 7717d36db35SAvi Kivity "mov $0x123, %ax\n\t" 7727d36db35SAvi Kivity "mov %ax, %es\n\t" 7737d36db35SAvi Kivity "push %es\n\t" 7747d36db35SAvi Kivity "pop %bx \n\t" 7757d36db35SAvi Kivity ); 7767d36db35SAvi Kivity MK_INSN(pop_es, "push %ax\n\t" 7777d36db35SAvi Kivity "pop %es\n\t" 7787d36db35SAvi Kivity "mov %es, %bx\n\t" 7797d36db35SAvi Kivity ); 7807d36db35SAvi Kivity MK_INSN(push_pop_ss, "push %ss\n\t" 7817d36db35SAvi Kivity "pushw %ax\n\t" 7827d36db35SAvi Kivity "popw %ss\n\t" 7837d36db35SAvi Kivity "mov %ss, %bx\n\t" 7847d36db35SAvi Kivity "pop %ss\n\t" 7857d36db35SAvi Kivity ); 7867d36db35SAvi Kivity MK_INSN(push_pop_fs, "push %fs\n\t" 7877d36db35SAvi Kivity "pushl %eax\n\t" 7887d36db35SAvi Kivity "popl %fs\n\t" 7897d36db35SAvi Kivity "mov %fs, %ebx\n\t" 7907d36db35SAvi Kivity "pop %fs\n\t" 7917d36db35SAvi Kivity ); 7927d36db35SAvi Kivity 7937d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7947d36db35SAvi Kivity insn_push32, 7957d36db35SAvi Kivity insn_push32_end - insn_push32); 7967d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x12345678) 7977d36db35SAvi Kivity print_serial("Push/Pop Test 1: FAIL\n"); 7987d36db35SAvi Kivity else 7997d36db35SAvi Kivity print_serial("Push/Pop Test 1: PASS\n"); 8007d36db35SAvi Kivity 8017d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8027d36db35SAvi Kivity insn_push16, 8037d36db35SAvi Kivity insn_push16_end - insn_push16); 8047d36db35SAvi Kivity 8057d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x1234) 8067d36db35SAvi Kivity print_serial("Push/Pop Test 2: FAIL\n"); 8077d36db35SAvi Kivity else 8087d36db35SAvi Kivity print_serial("Push/Pop Test 2: PASS\n"); 8097d36db35SAvi Kivity 8107d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8117d36db35SAvi Kivity insn_push_es, 8127d36db35SAvi Kivity insn_push_es_end - insn_push_es); 8137d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax || outregs.eax != 0x123) 8147d36db35SAvi Kivity print_serial("Push/Pop Test 3: FAIL\n"); 8157d36db35SAvi Kivity else 8167d36db35SAvi Kivity print_serial("Push/Pop Test 3: PASS\n"); 8177d36db35SAvi Kivity 8187d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8197d36db35SAvi Kivity insn_pop_es, 8207d36db35SAvi Kivity insn_pop_es_end - insn_pop_es); 8217d36db35SAvi Kivity 8227d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) 8237d36db35SAvi Kivity print_serial("Push/Pop Test 4: FAIL\n"); 8247d36db35SAvi Kivity else 8257d36db35SAvi Kivity print_serial("Push/Pop Test 4: PASS\n"); 8267d36db35SAvi Kivity 8277d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8287d36db35SAvi Kivity insn_push_pop_ss, 8297d36db35SAvi Kivity insn_push_pop_ss_end - insn_push_pop_ss); 8307d36db35SAvi Kivity 8317d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) 8327d36db35SAvi Kivity print_serial("Push/Pop Test 5: FAIL\n"); 8337d36db35SAvi Kivity else 8347d36db35SAvi Kivity print_serial("Push/Pop Test 5: PASS\n"); 8357d36db35SAvi Kivity 8367d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8377d36db35SAvi Kivity insn_push_pop_fs, 8387d36db35SAvi Kivity insn_push_pop_fs_end - insn_push_pop_fs); 8397d36db35SAvi Kivity 8407d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) 8417d36db35SAvi Kivity print_serial("Push/Pop Test 6: FAIL\n"); 8427d36db35SAvi Kivity else 8437d36db35SAvi Kivity print_serial("Push/Pop Test 6: PASS\n"); 8447d36db35SAvi Kivity } 8457d36db35SAvi Kivity 8467d36db35SAvi Kivity void test_null(void) 8477d36db35SAvi Kivity { 8487d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 8497d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 0, 0); 8507d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 8517d36db35SAvi Kivity print_serial("null test: FAIL\n"); 8527d36db35SAvi Kivity else 8537d36db35SAvi Kivity print_serial("null test: PASS\n"); 8547d36db35SAvi Kivity } 8557d36db35SAvi Kivity 8567d36db35SAvi Kivity struct { 8577d36db35SAvi Kivity char stack[500]; 8587d36db35SAvi Kivity char top[]; 8597d36db35SAvi Kivity } tmp_stack; 8607d36db35SAvi Kivity 8617d36db35SAvi Kivity void test_pusha_popa() 8627d36db35SAvi Kivity { 8637d36db35SAvi 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; 8647d36db35SAvi Kivity 8657d36db35SAvi Kivity MK_INSN(pusha, "pusha\n\t" 8667d36db35SAvi Kivity "pop %edi\n\t" 8677d36db35SAvi Kivity "pop %esi\n\t" 8687d36db35SAvi Kivity "pop %ebp\n\t" 8697d36db35SAvi Kivity "add $4, %esp\n\t" 8707d36db35SAvi Kivity "pop %ebx\n\t" 8717d36db35SAvi Kivity "pop %edx\n\t" 8727d36db35SAvi Kivity "pop %ecx\n\t" 8737d36db35SAvi Kivity "pop %eax\n\t" 8747d36db35SAvi Kivity ); 8757d36db35SAvi Kivity 8767d36db35SAvi Kivity MK_INSN(popa, "push %eax\n\t" 8777d36db35SAvi Kivity "push %ecx\n\t" 8787d36db35SAvi Kivity "push %edx\n\t" 8797d36db35SAvi Kivity "push %ebx\n\t" 8807d36db35SAvi Kivity "push %esp\n\t" 8817d36db35SAvi Kivity "push %ebp\n\t" 8827d36db35SAvi Kivity "push %esi\n\t" 8837d36db35SAvi Kivity "push %edi\n\t" 8847d36db35SAvi Kivity "popa\n\t" 8857d36db35SAvi Kivity ); 8867d36db35SAvi Kivity 8877d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8887d36db35SAvi Kivity insn_pusha, 8897d36db35SAvi Kivity insn_pusha_end - insn_pusha); 8907d36db35SAvi Kivity 8917d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 8927d36db35SAvi Kivity print_serial("Pusha/Popa Test1: FAIL\n"); 8937d36db35SAvi Kivity else 8947d36db35SAvi Kivity print_serial("Pusha/Popa Test1: PASS\n"); 8957d36db35SAvi Kivity 8967d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8977d36db35SAvi Kivity insn_popa, 8987d36db35SAvi Kivity insn_popa_end - insn_popa); 8997d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 9007d36db35SAvi Kivity print_serial("Pusha/Popa Test2: FAIL\n"); 9017d36db35SAvi Kivity else 9027d36db35SAvi Kivity print_serial("Pusha/Popa Test2: PASS\n"); 9037d36db35SAvi Kivity } 9047d36db35SAvi Kivity 9057d36db35SAvi Kivity void test_iret() 9067d36db35SAvi Kivity { 9077d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 9087d36db35SAvi Kivity 9097d36db35SAvi Kivity MK_INSN(iret32, "pushf\n\t" 9107d36db35SAvi Kivity "pushl %cs\n\t" 9117d36db35SAvi Kivity "call 1f\n\t" /* a near call will push eip onto the stack */ 9127d36db35SAvi Kivity "jmp 2f\n\t" 9137d36db35SAvi Kivity "1: iret\n\t" 9147d36db35SAvi Kivity "2:\n\t" 9157d36db35SAvi Kivity ); 9167d36db35SAvi Kivity 9177d36db35SAvi Kivity MK_INSN(iret16, "pushfw\n\t" 9187d36db35SAvi Kivity "pushw %cs\n\t" 9197d36db35SAvi Kivity "callw 1f\n\t" 9207d36db35SAvi Kivity "jmp 2f\n\t" 9217d36db35SAvi Kivity "1: iretw\n\t" 9227d36db35SAvi Kivity "2:\n\t"); 9237d36db35SAvi Kivity 9247d36db35SAvi Kivity MK_INSN(iret_flags32, "pushfl\n\t" 9257d36db35SAvi Kivity "popl %eax\n\t" 9267d36db35SAvi Kivity "andl $~0x2, %eax\n\t" 9277d36db35SAvi Kivity "orl $0xffc08028, %eax\n\t" 9287d36db35SAvi Kivity "pushl %eax\n\t" 9297d36db35SAvi Kivity "pushl %cs\n\t" 9307d36db35SAvi Kivity "call 1f\n\t" 9317d36db35SAvi Kivity "jmp 2f\n\t" 9327d36db35SAvi Kivity "1: iret\n\t" 9337d36db35SAvi Kivity "2:\n\t"); 9347d36db35SAvi Kivity 9357d36db35SAvi Kivity MK_INSN(iret_flags16, "pushfw\n\t" 9367d36db35SAvi Kivity "popw %ax\n\t" 9377d36db35SAvi Kivity "and $~0x2, %ax\n\t" 9387d36db35SAvi Kivity "or $0x8028, %ax\n\t" 9397d36db35SAvi Kivity "pushw %ax\n\t" 9407d36db35SAvi Kivity "pushw %cs\n\t" 9417d36db35SAvi Kivity "callw 1f\n\t" 9427d36db35SAvi Kivity "jmp 2f\n\t" 9437d36db35SAvi Kivity "1: iretw\n\t" 9447d36db35SAvi Kivity "2:\n\t"); 9457d36db35SAvi Kivity 9467d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 9477d36db35SAvi Kivity insn_iret32, 9487d36db35SAvi Kivity insn_iret32_end - insn_iret32); 9497d36db35SAvi Kivity 9507d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 9517d36db35SAvi Kivity print_serial("iret Test 1: FAIL\n"); 9527d36db35SAvi Kivity else 9537d36db35SAvi Kivity print_serial("iret Test 1: PASS\n"); 9547d36db35SAvi Kivity 9557d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 9567d36db35SAvi Kivity insn_iret16, 9577d36db35SAvi Kivity insn_iret16_end - insn_iret16); 9587d36db35SAvi Kivity 9597d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 9607d36db35SAvi Kivity print_serial("iret Test 2: FAIL\n"); 9617d36db35SAvi Kivity else 9627d36db35SAvi Kivity print_serial("iret Test 2: PASS\n"); 9637d36db35SAvi Kivity 9647d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 9657d36db35SAvi Kivity insn_iret_flags32, 9667d36db35SAvi Kivity insn_iret_flags32_end - insn_iret_flags32); 9677d36db35SAvi Kivity 9687d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX)) 9697d36db35SAvi Kivity print_serial("iret Test 3: FAIL\n"); 9707d36db35SAvi Kivity else 9717d36db35SAvi Kivity print_serial("iret Test 3: PASS\n"); 9727d36db35SAvi Kivity 9737d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 9747d36db35SAvi Kivity insn_iret_flags16, 9757d36db35SAvi Kivity insn_iret_flags16_end - insn_iret_flags16); 9767d36db35SAvi Kivity 9777d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX)) 9787d36db35SAvi Kivity print_serial("iret Test 4: FAIL\n"); 9797d36db35SAvi Kivity else 9807d36db35SAvi Kivity print_serial("iret Test 4: PASS\n"); 9817d36db35SAvi Kivity } 9827d36db35SAvi Kivity 98396b9ca1eSMohammed Gamal void test_int() 98496b9ca1eSMohammed Gamal { 98596b9ca1eSMohammed Gamal struct regs inregs = { 0 }, outregs; 98696b9ca1eSMohammed Gamal 98796b9ca1eSMohammed Gamal *(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */ 98896b9ca1eSMohammed Gamal *(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */ 98996b9ca1eSMohammed Gamal 99096b9ca1eSMohammed Gamal MK_INSN(int11, "int $0x11\n\t"); 99196b9ca1eSMohammed Gamal 99296b9ca1eSMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 99396b9ca1eSMohammed Gamal insn_int11, 99496b9ca1eSMohammed Gamal insn_int11_end - insn_int11); 99596b9ca1eSMohammed Gamal 99696b9ca1eSMohammed Gamal if (!regs_equal(&inregs, &outregs, 0)) 99796b9ca1eSMohammed Gamal print_serial("int Test 1: FAIL\n"); 99896b9ca1eSMohammed Gamal else 99996b9ca1eSMohammed Gamal print_serial("int Test 1: PASS\n"); 100096b9ca1eSMohammed Gamal } 100196b9ca1eSMohammed Gamal 1002fa74f8a6SMohammed Gamal void test_imul() 1003fa74f8a6SMohammed Gamal { 1004fa74f8a6SMohammed Gamal struct regs inregs = { 0 }, outregs; 1005fa74f8a6SMohammed Gamal 1006fa74f8a6SMohammed Gamal MK_INSN(imul8_1, "mov $2, %al\n\t" 1007fa74f8a6SMohammed Gamal "mov $-4, %cx\n\t" 1008fa74f8a6SMohammed Gamal "imul %cl\n\t"); 1009fa74f8a6SMohammed Gamal 1010fa74f8a6SMohammed Gamal MK_INSN(imul16_1, "mov $2, %ax\n\t" 1011fa74f8a6SMohammed Gamal "mov $-4, %cx\n\t" 1012fa74f8a6SMohammed Gamal "imul %cx\n\t"); 1013fa74f8a6SMohammed Gamal 1014fa74f8a6SMohammed Gamal MK_INSN(imul32_1, "mov $2, %eax\n\t" 1015fa74f8a6SMohammed Gamal "mov $-4, %ecx\n\t" 1016fa74f8a6SMohammed Gamal "imul %ecx\n\t"); 1017fa74f8a6SMohammed Gamal 1018fa74f8a6SMohammed Gamal MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t" 1019fa74f8a6SMohammed Gamal "mov $4, %cx\n\t" 1020fa74f8a6SMohammed Gamal "imul %cl\n\t"); 1021fa74f8a6SMohammed Gamal 1022fa74f8a6SMohammed Gamal MK_INSN(imul16_2, "mov $2, %ax\n\t" 1023fa74f8a6SMohammed Gamal "mov $4, %cx\n\t" 1024fa74f8a6SMohammed Gamal "imul %cx\n\t"); 1025fa74f8a6SMohammed Gamal 1026fa74f8a6SMohammed Gamal MK_INSN(imul32_2, "mov $2, %eax\n\t" 1027fa74f8a6SMohammed Gamal "mov $4, %ecx\n\t" 1028fa74f8a6SMohammed Gamal "imul %ecx\n\t"); 1029fa74f8a6SMohammed Gamal 1030fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1031fa74f8a6SMohammed Gamal insn_imul8_1, 1032fa74f8a6SMohammed Gamal insn_imul8_1_end - insn_imul8_1); 1033fa74f8a6SMohammed Gamal 1034fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != (u8)-8) 1035fa74f8a6SMohammed Gamal print_serial("imul Test 1: FAIL\n"); 1036fa74f8a6SMohammed Gamal else 1037fa74f8a6SMohammed Gamal print_serial("imul Test 1: PASS\n"); 1038fa74f8a6SMohammed Gamal 1039fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1040fa74f8a6SMohammed Gamal insn_imul16_1, 1041fa74f8a6SMohammed Gamal insn_imul16_1_end - insn_imul16_1); 1042fa74f8a6SMohammed Gamal 1043fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-8) 1044fa74f8a6SMohammed Gamal print_serial("imul Test 2: FAIL\n"); 1045fa74f8a6SMohammed Gamal else 1046fa74f8a6SMohammed Gamal print_serial("imul Test 2: PASS\n"); 1047fa74f8a6SMohammed Gamal 1048fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1049fa74f8a6SMohammed Gamal insn_imul32_1, 1050fa74f8a6SMohammed Gamal insn_imul32_1_end - insn_imul32_1); 1051fa74f8a6SMohammed Gamal 1052fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-8) 1053fa74f8a6SMohammed Gamal print_serial("imul Test 3: FAIL\n"); 1054fa74f8a6SMohammed Gamal else 1055fa74f8a6SMohammed Gamal print_serial("imul Test 3: PASS\n"); 1056fa74f8a6SMohammed Gamal 1057fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1058fa74f8a6SMohammed Gamal insn_imul8_2, 1059fa74f8a6SMohammed Gamal insn_imul8_2_end - insn_imul8_2); 1060fa74f8a6SMohammed Gamal 1061fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xffff) != 8 || 1062fa74f8a6SMohammed Gamal (outregs.eax & 0xffff0000) != 0x12340000) 1063fa74f8a6SMohammed Gamal print_serial("imul Test 4: FAIL\n"); 1064fa74f8a6SMohammed Gamal else 1065fa74f8a6SMohammed Gamal print_serial("imul Test 4: PASS\n"); 1066fa74f8a6SMohammed Gamal 1067fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1068fa74f8a6SMohammed Gamal insn_imul16_2, 1069fa74f8a6SMohammed Gamal insn_imul16_2_end - insn_imul16_2); 1070fa74f8a6SMohammed Gamal 1071fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 1072fa74f8a6SMohammed Gamal print_serial("imul Test 5: FAIL\n"); 1073fa74f8a6SMohammed Gamal else 1074fa74f8a6SMohammed Gamal print_serial("imul Test 5: PASS\n"); 1075fa74f8a6SMohammed Gamal 1076fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1077fa74f8a6SMohammed Gamal insn_imul32_2, 1078fa74f8a6SMohammed Gamal insn_imul32_2_end - insn_imul32_2); 1079fa74f8a6SMohammed Gamal 1080fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 1081fa74f8a6SMohammed Gamal print_serial("imul Test 6: FAIL\n"); 1082fa74f8a6SMohammed Gamal else 1083fa74f8a6SMohammed Gamal print_serial("imul Test 6: PASS\n"); 1084fa74f8a6SMohammed Gamal } 1085fa74f8a6SMohammed Gamal 108659317bd1SMohammed Gamal void test_mul() 108759317bd1SMohammed Gamal { 108859317bd1SMohammed Gamal struct regs inregs = { 0 }, outregs; 108959317bd1SMohammed Gamal 109059317bd1SMohammed Gamal MK_INSN(mul8, "mov $2, %al\n\t" 109159317bd1SMohammed Gamal "mov $4, %cx\n\t" 109259317bd1SMohammed Gamal "imul %cl\n\t"); 109359317bd1SMohammed Gamal 109459317bd1SMohammed Gamal MK_INSN(mul16, "mov $2, %ax\n\t" 109559317bd1SMohammed Gamal "mov $4, %cx\n\t" 109659317bd1SMohammed Gamal "imul %cx\n\t"); 109759317bd1SMohammed Gamal 109859317bd1SMohammed Gamal MK_INSN(mul32, "mov $2, %eax\n\t" 109959317bd1SMohammed Gamal "mov $4, %ecx\n\t" 110059317bd1SMohammed Gamal "imul %ecx\n\t"); 110159317bd1SMohammed Gamal 110259317bd1SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 110359317bd1SMohammed Gamal insn_mul8, 110459317bd1SMohammed Gamal insn_mul8_end - insn_mul8); 110559317bd1SMohammed Gamal 110659317bd1SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != 8) 110759317bd1SMohammed Gamal print_serial("mul Test 1: FAIL\n"); 110859317bd1SMohammed Gamal else 110959317bd1SMohammed Gamal print_serial("mul Test 1: PASS\n"); 111059317bd1SMohammed Gamal 111159317bd1SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 111259317bd1SMohammed Gamal insn_mul16, 111359317bd1SMohammed Gamal insn_mul16_end - insn_mul16); 111459317bd1SMohammed Gamal 111559317bd1SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 111659317bd1SMohammed Gamal print_serial("mul Test 2: FAIL\n"); 111759317bd1SMohammed Gamal else 111859317bd1SMohammed Gamal print_serial("mul Test 2: PASS\n"); 111959317bd1SMohammed Gamal 112059317bd1SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 112159317bd1SMohammed Gamal insn_mul32, 112259317bd1SMohammed Gamal insn_mul32_end - insn_mul32); 112359317bd1SMohammed Gamal 112459317bd1SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 112559317bd1SMohammed Gamal print_serial("mul Test 3: FAIL\n"); 112659317bd1SMohammed Gamal else 112759317bd1SMohammed Gamal print_serial("mul Test 3: PASS\n"); 112859317bd1SMohammed Gamal } 112959317bd1SMohammed Gamal 11300d4c7614SMohammed Gamal void test_div() 11310d4c7614SMohammed Gamal { 11320d4c7614SMohammed Gamal struct regs inregs = { 0 }, outregs; 11330d4c7614SMohammed Gamal 11340d4c7614SMohammed Gamal MK_INSN(div8, "mov $257, %ax\n\t" 11350d4c7614SMohammed Gamal "mov $2, %cl\n\t" 11360d4c7614SMohammed Gamal "div %cl\n\t"); 11370d4c7614SMohammed Gamal 11380d4c7614SMohammed Gamal MK_INSN(div16, "mov $512, %ax\n\t" 11390d4c7614SMohammed Gamal "mov $5, %cx\n\t" 11400d4c7614SMohammed Gamal "div %cx\n\t"); 11410d4c7614SMohammed Gamal 11420d4c7614SMohammed Gamal MK_INSN(div32, "mov $512, %eax\n\t" 11430d4c7614SMohammed Gamal "mov $5, %ecx\n\t" 11440d4c7614SMohammed Gamal "div %ecx\n\t"); 11450d4c7614SMohammed Gamal 11460d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11470d4c7614SMohammed Gamal insn_div8, 11480d4c7614SMohammed Gamal insn_div8_end - insn_div8); 11490d4c7614SMohammed Gamal 11500d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 384) 11510d4c7614SMohammed Gamal print_serial("div Test 1: FAIL\n"); 11520d4c7614SMohammed Gamal else 11530d4c7614SMohammed Gamal print_serial("div Test 1: PASS\n"); 11540d4c7614SMohammed Gamal 11550d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11560d4c7614SMohammed Gamal insn_div16, 11570d4c7614SMohammed Gamal insn_div16_end - insn_div16); 11580d4c7614SMohammed Gamal 11590d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 || 11600d4c7614SMohammed Gamal outregs.edx != 2) 11610d4c7614SMohammed Gamal print_serial("div Test 2: FAIL\n"); 11620d4c7614SMohammed Gamal else 11630d4c7614SMohammed Gamal print_serial("div Test 2: PASS\n"); 11640d4c7614SMohammed Gamal 11650d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11660d4c7614SMohammed Gamal insn_div32, 11670d4c7614SMohammed Gamal insn_div32_end - insn_div32); 11680d4c7614SMohammed Gamal 11690d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 || 11700d4c7614SMohammed Gamal outregs.edx != 2) 11710d4c7614SMohammed Gamal print_serial("div Test 3: FAIL\n"); 11720d4c7614SMohammed Gamal else 11730d4c7614SMohammed Gamal print_serial("div Test 3: PASS\n"); 11740d4c7614SMohammed Gamal } 11750d4c7614SMohammed Gamal 11760d4c7614SMohammed Gamal void test_idiv() 11770d4c7614SMohammed Gamal { 11780d4c7614SMohammed Gamal struct regs inregs = { 0 }, outregs; 11790d4c7614SMohammed Gamal 11800d4c7614SMohammed Gamal MK_INSN(idiv8, "mov $256, %ax\n\t" 11810d4c7614SMohammed Gamal "mov $-2, %cl\n\t" 11820d4c7614SMohammed Gamal "idiv %cl\n\t"); 11830d4c7614SMohammed Gamal 11840d4c7614SMohammed Gamal MK_INSN(idiv16, "mov $512, %ax\n\t" 11850d4c7614SMohammed Gamal "mov $-2, %cx\n\t" 11860d4c7614SMohammed Gamal "idiv %cx\n\t"); 11870d4c7614SMohammed Gamal 11880d4c7614SMohammed Gamal MK_INSN(idiv32, "mov $512, %eax\n\t" 11890d4c7614SMohammed Gamal "mov $-2, %ecx\n\t" 11900d4c7614SMohammed Gamal "idiv %ecx\n\t"); 11910d4c7614SMohammed Gamal 11920d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11930d4c7614SMohammed Gamal insn_idiv8, 11940d4c7614SMohammed Gamal insn_idiv8_end - insn_idiv8); 11950d4c7614SMohammed Gamal 11960d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u8)-128) 11970d4c7614SMohammed Gamal print_serial("idiv Test 1: FAIL\n"); 11980d4c7614SMohammed Gamal else 11990d4c7614SMohammed Gamal print_serial("idiv Test 1: PASS\n"); 12000d4c7614SMohammed Gamal 12010d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 12020d4c7614SMohammed Gamal insn_idiv16, 12030d4c7614SMohammed Gamal insn_idiv16_end - insn_idiv16); 12040d4c7614SMohammed Gamal 12050d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-256) 12060d4c7614SMohammed Gamal print_serial("idiv Test 2: FAIL\n"); 12070d4c7614SMohammed Gamal else 12080d4c7614SMohammed Gamal print_serial("idiv Test 2: PASS\n"); 12090d4c7614SMohammed Gamal 12100d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 12110d4c7614SMohammed Gamal insn_idiv32, 12120d4c7614SMohammed Gamal insn_idiv32_end - insn_idiv32); 12130d4c7614SMohammed Gamal 12140d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-256) 12150d4c7614SMohammed Gamal print_serial("idiv Test 3: FAIL\n"); 12160d4c7614SMohammed Gamal else 12170d4c7614SMohammed Gamal print_serial("idiv Test 3: PASS\n"); 12180d4c7614SMohammed Gamal } 12190d4c7614SMohammed Gamal 12206e293cf5SWei Yongjun void test_cbw(void) 12216e293cf5SWei Yongjun { 12226e293cf5SWei Yongjun struct regs inregs = { 0 }, outregs; 12236e293cf5SWei Yongjun 12246e293cf5SWei Yongjun MK_INSN(cbw, "mov $0xFE, %eax \n\t" 12256e293cf5SWei Yongjun "cbw\n\t"); 12266e293cf5SWei Yongjun MK_INSN(cwde, "mov $0xFFFE, %eax \n\t" 12276e293cf5SWei Yongjun "cwde\n\t"); 12286e293cf5SWei Yongjun 12296e293cf5SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 12306e293cf5SWei Yongjun insn_cbw, 12316e293cf5SWei Yongjun insn_cbw_end - insn_cbw); 12326e293cf5SWei Yongjun if (outregs.eax != 0xFFFE) 12336e293cf5SWei Yongjun print_serial("cbw test1: FAIL\n"); 12346e293cf5SWei Yongjun else 12356e293cf5SWei Yongjun print_serial("cbw test 1: PASS\n"); 12366e293cf5SWei Yongjun 12376e293cf5SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 12386e293cf5SWei Yongjun insn_cwde, 12396e293cf5SWei Yongjun insn_cwde_end - insn_cwde); 12406e293cf5SWei Yongjun if (outregs.eax != 0xFFFFFFFE) 12416e293cf5SWei Yongjun print_serial("cwde test1: FAIL\n"); 12426e293cf5SWei Yongjun else 12436e293cf5SWei Yongjun print_serial("cwde test 1: PASS\n"); 12446e293cf5SWei Yongjun } 12456e293cf5SWei Yongjun 1246eacef4e2SWei Yongjun void test_loopcc(void) 1247eacef4e2SWei Yongjun { 1248eacef4e2SWei Yongjun struct regs inregs = { 0 }, outregs; 1249eacef4e2SWei Yongjun 1250eacef4e2SWei Yongjun MK_INSN(loop, "mov $10, %ecx\n\t" 1251eacef4e2SWei Yongjun "1: inc %eax\n\t" 1252eacef4e2SWei Yongjun "loop 1b\n\t"); 1253eacef4e2SWei Yongjun 1254eacef4e2SWei Yongjun MK_INSN(loope, "mov $10, %ecx\n\t" 1255eacef4e2SWei Yongjun "mov $1, %eax\n\t" 1256eacef4e2SWei Yongjun "1: dec %eax\n\t" 1257eacef4e2SWei Yongjun "loope 1b\n\t"); 1258eacef4e2SWei Yongjun 1259eacef4e2SWei Yongjun MK_INSN(loopne, "mov $10, %ecx\n\t" 1260eacef4e2SWei Yongjun "mov $5, %eax\n\t" 1261eacef4e2SWei Yongjun "1: dec %eax\n\t" 1262eacef4e2SWei Yongjun "loopne 1b\n\t"); 1263eacef4e2SWei Yongjun 1264eacef4e2SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 1265eacef4e2SWei Yongjun insn_loop, insn_loop_end - insn_loop); 1266eacef4e2SWei Yongjun if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 10) 1267eacef4e2SWei Yongjun print_serial("LOOPcc short Test 1: FAIL\n"); 1268eacef4e2SWei Yongjun else 1269eacef4e2SWei Yongjun print_serial("LOOPcc short Test 1: PASS\n"); 1270eacef4e2SWei Yongjun 1271eacef4e2SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 1272eacef4e2SWei Yongjun insn_loope, insn_loope_end - insn_loope); 1273eacef4e2SWei Yongjun if(!regs_equal(&inregs, &outregs, R_AX | R_CX) || 1274eacef4e2SWei Yongjun outregs.eax != -1 || outregs.ecx != 8) 1275eacef4e2SWei Yongjun print_serial("LOOPcc short Test 2: FAIL\n"); 1276eacef4e2SWei Yongjun else 1277eacef4e2SWei Yongjun print_serial("LOOPcc short Test 2: PASS\n"); 1278eacef4e2SWei Yongjun 1279eacef4e2SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 1280eacef4e2SWei Yongjun insn_loopne, insn_loopne_end - insn_loopne); 1281eacef4e2SWei Yongjun if(!regs_equal(&inregs, &outregs, R_AX | R_CX) || 1282eacef4e2SWei Yongjun outregs.eax != 0 || outregs.ecx != 5) 1283eacef4e2SWei Yongjun print_serial("LOOPcc short Test 3: FAIL\n"); 1284eacef4e2SWei Yongjun else 1285eacef4e2SWei Yongjun print_serial("LOOPcc short Test 3: PASS\n"); 1286eacef4e2SWei Yongjun } 1287eacef4e2SWei Yongjun 1288b274feedSAvi Kivity static void test_das(void) 1289b274feedSAvi Kivity { 1290b274feedSAvi Kivity struct regs inregs = { 0 }, outregs = { 0 }; 1291b274feedSAvi Kivity short i; 1292b274feedSAvi Kivity static unsigned test_cases[1024] = { 1293b274feedSAvi Kivity 0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00, 1294b274feedSAvi Kivity 0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01, 1295b274feedSAvi Kivity 0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02, 1296b274feedSAvi Kivity 0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03, 1297b274feedSAvi Kivity 0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04, 1298b274feedSAvi Kivity 0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05, 1299b274feedSAvi Kivity 0x06000606, 0x8701a606, 0x56100006, 0x9711a006, 1300b274feedSAvi Kivity 0x02000707, 0x8301a707, 0x12100107, 0x9311a107, 1301b274feedSAvi Kivity 0x02000808, 0x8301a808, 0x12100208, 0x9311a208, 1302b274feedSAvi Kivity 0x06000909, 0x8701a909, 0x16100309, 0x9711a309, 1303b274feedSAvi Kivity 0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a, 1304b274feedSAvi Kivity 0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b, 1305b274feedSAvi Kivity 0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c, 1306b274feedSAvi Kivity 0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d, 1307b274feedSAvi Kivity 0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e, 1308b274feedSAvi Kivity 0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f, 1309b274feedSAvi Kivity 0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10, 1310b274feedSAvi Kivity 0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11, 1311b274feedSAvi Kivity 0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12, 1312b274feedSAvi Kivity 0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13, 1313b274feedSAvi Kivity 0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14, 1314b274feedSAvi Kivity 0x02001515, 0x8301b515, 0x16100f15, 0x9711af15, 1315b274feedSAvi Kivity 0x02001616, 0x8301b616, 0x12101016, 0x9311b016, 1316b274feedSAvi Kivity 0x06001717, 0x8701b717, 0x16101117, 0x9711b117, 1317b274feedSAvi Kivity 0x06001818, 0x8701b818, 0x16101218, 0x9711b218, 1318b274feedSAvi Kivity 0x02001919, 0x8301b919, 0x12101319, 0x9311b319, 1319b274feedSAvi Kivity 0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a, 1320b274feedSAvi Kivity 0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b, 1321b274feedSAvi Kivity 0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c, 1322b274feedSAvi Kivity 0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d, 1323b274feedSAvi Kivity 0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e, 1324b274feedSAvi Kivity 0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f, 1325b274feedSAvi Kivity 0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20, 1326b274feedSAvi Kivity 0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21, 1327b274feedSAvi Kivity 0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22, 1328b274feedSAvi Kivity 0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23, 1329b274feedSAvi Kivity 0x06002424, 0x8301c424, 0x16101e24, 0x9711be24, 1330b274feedSAvi Kivity 0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25, 1331b274feedSAvi Kivity 0x02002626, 0x8701c626, 0x12102026, 0x9711c026, 1332b274feedSAvi Kivity 0x06002727, 0x8301c727, 0x16102127, 0x9311c127, 1333b274feedSAvi Kivity 0x06002828, 0x8301c828, 0x16102228, 0x9311c228, 1334b274feedSAvi Kivity 0x02002929, 0x8701c929, 0x12102329, 0x9711c329, 1335b274feedSAvi Kivity 0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a, 1336b274feedSAvi Kivity 0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b, 1337b274feedSAvi Kivity 0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c, 1338b274feedSAvi Kivity 0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d, 1339b274feedSAvi Kivity 0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e, 1340b274feedSAvi Kivity 0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f, 1341b274feedSAvi Kivity 0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30, 1342b274feedSAvi Kivity 0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31, 1343b274feedSAvi Kivity 0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32, 1344b274feedSAvi Kivity 0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33, 1345b274feedSAvi Kivity 0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34, 1346b274feedSAvi Kivity 0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35, 1347b274feedSAvi Kivity 0x06003636, 0x8301d636, 0x16103036, 0x9311d036, 1348b274feedSAvi Kivity 0x02003737, 0x8701d737, 0x12103137, 0x9711d137, 1349b274feedSAvi Kivity 0x02003838, 0x8701d838, 0x12103238, 0x9711d238, 1350b274feedSAvi Kivity 0x06003939, 0x8301d939, 0x16103339, 0x9311d339, 1351b274feedSAvi Kivity 0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a, 1352b274feedSAvi Kivity 0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b, 1353b274feedSAvi Kivity 0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c, 1354b274feedSAvi Kivity 0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d, 1355b274feedSAvi Kivity 0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e, 1356b274feedSAvi Kivity 0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f, 1357b274feedSAvi Kivity 0x02004040, 0x8301e040, 0x16103a40, 0x9311da40, 1358b274feedSAvi Kivity 0x06004141, 0x8701e141, 0x12103b41, 0x9711db41, 1359b274feedSAvi Kivity 0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42, 1360b274feedSAvi Kivity 0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43, 1361b274feedSAvi Kivity 0x06004444, 0x8701e444, 0x12103e44, 0x9711de44, 1362b274feedSAvi Kivity 0x02004545, 0x8301e545, 0x16103f45, 0x9311df45, 1363b274feedSAvi Kivity 0x02004646, 0x8301e646, 0x12104046, 0x9311e046, 1364b274feedSAvi Kivity 0x06004747, 0x8701e747, 0x16104147, 0x9711e147, 1365b274feedSAvi Kivity 0x06004848, 0x8701e848, 0x16104248, 0x9711e248, 1366b274feedSAvi Kivity 0x02004949, 0x8301e949, 0x12104349, 0x9311e349, 1367b274feedSAvi Kivity 0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a, 1368b274feedSAvi Kivity 0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b, 1369b274feedSAvi Kivity 0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c, 1370b274feedSAvi Kivity 0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d, 1371b274feedSAvi Kivity 0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e, 1372b274feedSAvi Kivity 0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f, 1373b274feedSAvi Kivity 0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50, 1374b274feedSAvi Kivity 0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51, 1375b274feedSAvi Kivity 0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52, 1376b274feedSAvi Kivity 0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53, 1377b274feedSAvi Kivity 0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54, 1378b274feedSAvi Kivity 0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55, 1379b274feedSAvi Kivity 0x06005656, 0x8701f656, 0x16105056, 0x9711f056, 1380b274feedSAvi Kivity 0x02005757, 0x8301f757, 0x12105157, 0x9311f157, 1381b274feedSAvi Kivity 0x02005858, 0x8301f858, 0x12105258, 0x9311f258, 1382b274feedSAvi Kivity 0x06005959, 0x8701f959, 0x16105359, 0x9711f359, 1383b274feedSAvi Kivity 0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a, 1384b274feedSAvi Kivity 0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b, 1385b274feedSAvi Kivity 0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c, 1386b274feedSAvi Kivity 0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d, 1387b274feedSAvi Kivity 0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e, 1388b274feedSAvi Kivity 0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f, 1389b274feedSAvi Kivity 0x06006060, 0x47010060, 0x16105a60, 0x9711fa60, 1390b274feedSAvi Kivity 0x02006161, 0x03010161, 0x12105b61, 0x9311fb61, 1391b274feedSAvi Kivity 0x02006262, 0x03010262, 0x16105c62, 0x9711fc62, 1392b274feedSAvi Kivity 0x06006363, 0x07010363, 0x12105d63, 0x9311fd63, 1393b274feedSAvi Kivity 0x02006464, 0x03010464, 0x12105e64, 0x9311fe64, 1394b274feedSAvi Kivity 0x06006565, 0x07010565, 0x16105f65, 0x9711ff65, 1395b274feedSAvi Kivity 0x06006666, 0x07010666, 0x16106066, 0x57110066, 1396b274feedSAvi Kivity 0x02006767, 0x03010767, 0x12106167, 0x13110167, 1397b274feedSAvi Kivity 0x02006868, 0x03010868, 0x12106268, 0x13110268, 1398b274feedSAvi Kivity 0x06006969, 0x07010969, 0x16106369, 0x17110369, 1399b274feedSAvi Kivity 0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a, 1400b274feedSAvi Kivity 0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b, 1401b274feedSAvi Kivity 0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c, 1402b274feedSAvi Kivity 0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d, 1403b274feedSAvi Kivity 0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e, 1404b274feedSAvi Kivity 0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f, 1405b274feedSAvi Kivity 0x02007070, 0x03011070, 0x16106a70, 0x17110a70, 1406b274feedSAvi Kivity 0x06007171, 0x07011171, 0x12106b71, 0x13110b71, 1407b274feedSAvi Kivity 0x06007272, 0x07011272, 0x16106c72, 0x17110c72, 1408b274feedSAvi Kivity 0x02007373, 0x03011373, 0x12106d73, 0x13110d73, 1409b274feedSAvi Kivity 0x06007474, 0x07011474, 0x12106e74, 0x13110e74, 1410b274feedSAvi Kivity 0x02007575, 0x03011575, 0x16106f75, 0x17110f75, 1411b274feedSAvi Kivity 0x02007676, 0x03011676, 0x12107076, 0x13111076, 1412b274feedSAvi Kivity 0x06007777, 0x07011777, 0x16107177, 0x17111177, 1413b274feedSAvi Kivity 0x06007878, 0x07011878, 0x16107278, 0x17111278, 1414b274feedSAvi Kivity 0x02007979, 0x03011979, 0x12107379, 0x13111379, 1415b274feedSAvi Kivity 0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a, 1416b274feedSAvi Kivity 0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b, 1417b274feedSAvi Kivity 0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c, 1418b274feedSAvi Kivity 0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d, 1419b274feedSAvi Kivity 0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e, 1420b274feedSAvi Kivity 0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f, 1421b274feedSAvi Kivity 0x82008080, 0x03012080, 0x12107a80, 0x13111a80, 1422b274feedSAvi Kivity 0x86008181, 0x07012181, 0x16107b81, 0x17111b81, 1423b274feedSAvi Kivity 0x86008282, 0x07012282, 0x12107c82, 0x13111c82, 1424b274feedSAvi Kivity 0x82008383, 0x03012383, 0x16107d83, 0x17111d83, 1425b274feedSAvi Kivity 0x86008484, 0x07012484, 0x16107e84, 0x17111e84, 1426b274feedSAvi Kivity 0x82008585, 0x03012585, 0x12107f85, 0x13111f85, 1427b274feedSAvi Kivity 0x82008686, 0x03012686, 0x92108086, 0x13112086, 1428b274feedSAvi Kivity 0x86008787, 0x07012787, 0x96108187, 0x17112187, 1429b274feedSAvi Kivity 0x86008888, 0x07012888, 0x96108288, 0x17112288, 1430b274feedSAvi Kivity 0x82008989, 0x03012989, 0x92108389, 0x13112389, 1431b274feedSAvi Kivity 0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a, 1432b274feedSAvi Kivity 0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b, 1433b274feedSAvi Kivity 0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c, 1434b274feedSAvi Kivity 0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d, 1435b274feedSAvi Kivity 0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e, 1436b274feedSAvi Kivity 0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f, 1437b274feedSAvi Kivity 0x86009090, 0x07013090, 0x92108a90, 0x13112a90, 1438b274feedSAvi Kivity 0x82009191, 0x03013191, 0x96108b91, 0x17112b91, 1439b274feedSAvi Kivity 0x82009292, 0x03013292, 0x92108c92, 0x13112c92, 1440b274feedSAvi Kivity 0x86009393, 0x07013393, 0x96108d93, 0x17112d93, 1441b274feedSAvi Kivity 0x82009494, 0x03013494, 0x96108e94, 0x17112e94, 1442b274feedSAvi Kivity 0x86009595, 0x07013595, 0x92108f95, 0x13112f95, 1443b274feedSAvi Kivity 0x86009696, 0x07013696, 0x96109096, 0x17113096, 1444b274feedSAvi Kivity 0x82009797, 0x03013797, 0x92109197, 0x13113197, 1445b274feedSAvi Kivity 0x82009898, 0x03013898, 0x92109298, 0x13113298, 1446b274feedSAvi Kivity 0x86009999, 0x07013999, 0x96109399, 0x17113399, 1447b274feedSAvi Kivity 0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a, 1448b274feedSAvi Kivity 0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b, 1449b274feedSAvi Kivity 0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c, 1450b274feedSAvi Kivity 0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d, 1451b274feedSAvi Kivity 0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e, 1452b274feedSAvi Kivity 0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f, 1453b274feedSAvi Kivity 0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0, 1454b274feedSAvi Kivity 0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1, 1455b274feedSAvi Kivity 0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2, 1456b274feedSAvi Kivity 0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3, 1457b274feedSAvi Kivity 0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4, 1458b274feedSAvi Kivity 0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5, 1459b274feedSAvi Kivity 0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6, 1460b274feedSAvi Kivity 0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7, 1461b274feedSAvi Kivity 0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8, 1462b274feedSAvi Kivity 0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9, 1463b274feedSAvi Kivity 0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa, 1464b274feedSAvi Kivity 0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab, 1465b274feedSAvi Kivity 0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac, 1466b274feedSAvi Kivity 0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad, 1467b274feedSAvi Kivity 0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae, 1468b274feedSAvi Kivity 0x130049af, 0x130149af, 0x131049af, 0x131149af, 1469b274feedSAvi Kivity 0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0, 1470b274feedSAvi Kivity 0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1, 1471b274feedSAvi Kivity 0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2, 1472b274feedSAvi Kivity 0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3, 1473b274feedSAvi Kivity 0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4, 1474b274feedSAvi Kivity 0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5, 1475b274feedSAvi Kivity 0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6, 1476b274feedSAvi Kivity 0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7, 1477b274feedSAvi Kivity 0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8, 1478b274feedSAvi Kivity 0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9, 1479b274feedSAvi Kivity 0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba, 1480b274feedSAvi Kivity 0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb, 1481b274feedSAvi Kivity 0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc, 1482b274feedSAvi Kivity 0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd, 1483b274feedSAvi Kivity 0x130058be, 0x130158be, 0x131058be, 0x131158be, 1484b274feedSAvi Kivity 0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf, 1485b274feedSAvi Kivity 0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0, 1486b274feedSAvi Kivity 0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1, 1487b274feedSAvi Kivity 0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2, 1488b274feedSAvi Kivity 0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3, 1489b274feedSAvi Kivity 0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4, 1490b274feedSAvi Kivity 0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5, 1491b274feedSAvi Kivity 0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6, 1492b274feedSAvi Kivity 0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7, 1493b274feedSAvi Kivity 0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8, 1494b274feedSAvi Kivity 0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9, 1495b274feedSAvi Kivity 0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca, 1496b274feedSAvi Kivity 0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb, 1497b274feedSAvi Kivity 0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc, 1498b274feedSAvi Kivity 0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd, 1499b274feedSAvi Kivity 0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce, 1500b274feedSAvi Kivity 0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf, 1501b274feedSAvi Kivity 0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0, 1502b274feedSAvi Kivity 0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1, 1503b274feedSAvi Kivity 0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2, 1504b274feedSAvi Kivity 0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3, 1505b274feedSAvi Kivity 0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4, 1506b274feedSAvi Kivity 0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5, 1507b274feedSAvi Kivity 0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6, 1508b274feedSAvi Kivity 0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7, 1509b274feedSAvi Kivity 0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8, 1510b274feedSAvi Kivity 0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9, 1511b274feedSAvi Kivity 0x170074da, 0x170174da, 0x171074da, 0x171174da, 1512b274feedSAvi Kivity 0x130075db, 0x130175db, 0x131075db, 0x131175db, 1513b274feedSAvi Kivity 0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc, 1514b274feedSAvi Kivity 0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd, 1515b274feedSAvi Kivity 0x170078de, 0x170178de, 0x171078de, 0x171178de, 1516b274feedSAvi Kivity 0x130079df, 0x130179df, 0x131079df, 0x131179df, 1517b274feedSAvi Kivity 0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0, 1518b274feedSAvi Kivity 0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1, 1519b274feedSAvi Kivity 0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2, 1520b274feedSAvi Kivity 0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3, 1521b274feedSAvi Kivity 0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4, 1522b274feedSAvi Kivity 0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5, 1523b274feedSAvi Kivity 0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6, 1524b274feedSAvi Kivity 0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7, 1525b274feedSAvi Kivity 0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8, 1526b274feedSAvi Kivity 0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9, 1527b274feedSAvi Kivity 0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea, 1528b274feedSAvi Kivity 0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb, 1529b274feedSAvi Kivity 0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec, 1530b274feedSAvi Kivity 0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed, 1531b274feedSAvi Kivity 0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee, 1532b274feedSAvi Kivity 0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef, 1533b274feedSAvi Kivity 0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0, 1534b274feedSAvi Kivity 0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1, 1535b274feedSAvi Kivity 0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2, 1536b274feedSAvi Kivity 0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3, 1537b274feedSAvi Kivity 0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4, 1538b274feedSAvi Kivity 0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5, 1539b274feedSAvi Kivity 0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6, 1540b274feedSAvi Kivity 0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7, 1541b274feedSAvi Kivity 0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8, 1542b274feedSAvi Kivity 0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9, 1543b274feedSAvi Kivity 0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa, 1544b274feedSAvi Kivity 0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb, 1545b274feedSAvi Kivity 0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc, 1546b274feedSAvi Kivity 0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd, 1547b274feedSAvi Kivity 0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe, 1548b274feedSAvi Kivity 0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff, 1549b274feedSAvi Kivity }; 1550b274feedSAvi Kivity 1551b274feedSAvi Kivity MK_INSN(das, "das"); 1552b274feedSAvi Kivity 1553b274feedSAvi Kivity for (i = 0; i < 1024; ++i) { 1554b274feedSAvi Kivity unsigned tmp = test_cases[i]; 1555b274feedSAvi Kivity inregs.eax = tmp & 0xff; 1556b274feedSAvi Kivity inregs.eflags = (tmp >> 16) & 0xff; 1557b274feedSAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1558b274feedSAvi Kivity insn_das, 1559b274feedSAvi Kivity insn_das_end - insn_das); 1560b274feedSAvi Kivity 1561b274feedSAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) 1562b274feedSAvi Kivity || outregs.eax != ((tmp >> 8) & 0xff) 1563b274feedSAvi Kivity || (outregs.eflags & 0xff) != (tmp >> 24)) { 1564b274feedSAvi Kivity print_serial("DAS Test: FAIL\n"); 1565b274feedSAvi Kivity return; 1566b274feedSAvi Kivity } 1567b274feedSAvi Kivity } 1568b274feedSAvi Kivity print_serial("DAS Test: PASS\n"); 1569b274feedSAvi Kivity } 1570b274feedSAvi Kivity 15710cbd5b06SMohammed Gamal void test_cwd_cdq() 15720cbd5b06SMohammed Gamal { 15730cbd5b06SMohammed Gamal struct regs inregs = { 0 }, outregs; 15740cbd5b06SMohammed Gamal 15750cbd5b06SMohammed Gamal /* Sign-bit set */ 15760cbd5b06SMohammed Gamal MK_INSN(cwd_1, "mov $0x8000, %ax\n\t" 15770cbd5b06SMohammed Gamal "cwd\n\t"); 15780cbd5b06SMohammed Gamal 15790cbd5b06SMohammed Gamal /* Sign-bit not set */ 15800cbd5b06SMohammed Gamal MK_INSN(cwd_2, "mov $0x1000, %ax\n\t" 15810cbd5b06SMohammed Gamal "cwd\n\t"); 15820cbd5b06SMohammed Gamal 15830cbd5b06SMohammed Gamal /* Sign-bit set */ 15840cbd5b06SMohammed Gamal MK_INSN(cdq_1, "mov $0x80000000, %eax\n\t" 15850cbd5b06SMohammed Gamal "cdq\n\t"); 15860cbd5b06SMohammed Gamal 15870cbd5b06SMohammed Gamal /* Sign-bit not set */ 15880cbd5b06SMohammed Gamal MK_INSN(cdq_2, "mov $0x10000000, %eax\n\t" 15890cbd5b06SMohammed Gamal "cdq\n\t"); 15900cbd5b06SMohammed Gamal 15910cbd5b06SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 15920cbd5b06SMohammed Gamal insn_cwd_1, 15930cbd5b06SMohammed Gamal insn_cwd_1_end - insn_cwd_1); 15940cbd5b06SMohammed Gamal 15950cbd5b06SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || outregs.eax != 0x8000 || outregs.edx != 0xffff) 15960cbd5b06SMohammed Gamal print_serial("cwd Test 1: FAIL\n"); 15970cbd5b06SMohammed Gamal else 15980cbd5b06SMohammed Gamal print_serial("cwd Test 1: PASS\n"); 15990cbd5b06SMohammed Gamal 16000cbd5b06SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 16010cbd5b06SMohammed Gamal insn_cwd_2, 16020cbd5b06SMohammed Gamal insn_cwd_2_end - insn_cwd_2); 16030cbd5b06SMohammed Gamal 16040cbd5b06SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || outregs.eax != 0x1000 || outregs.edx != 0) 16050cbd5b06SMohammed Gamal print_serial("cwd Test 2: FAIL\n"); 16060cbd5b06SMohammed Gamal else 16070cbd5b06SMohammed Gamal print_serial("cwd Test 2: PASS\n"); 16080cbd5b06SMohammed Gamal 16090cbd5b06SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 16100cbd5b06SMohammed Gamal insn_cdq_1, 16110cbd5b06SMohammed Gamal insn_cdq_1_end - insn_cdq_1); 16120cbd5b06SMohammed Gamal 16130cbd5b06SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || outregs.eax != 0x80000000 || outregs.edx != 0xffffffff) 16140cbd5b06SMohammed Gamal print_serial("cdq Test 1: FAIL\n"); 16150cbd5b06SMohammed Gamal else 16160cbd5b06SMohammed Gamal print_serial("cdq Test 1: PASS\n"); 16170cbd5b06SMohammed Gamal 16180cbd5b06SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 16190cbd5b06SMohammed Gamal insn_cdq_2, 16200cbd5b06SMohammed Gamal insn_cdq_2_end - insn_cdq_2); 16210cbd5b06SMohammed Gamal 16220cbd5b06SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || outregs.eax != 0x10000000 || outregs.edx != 0) 16230cbd5b06SMohammed Gamal print_serial("cdq Test 2: FAIL\n"); 16240cbd5b06SMohammed Gamal else 16250cbd5b06SMohammed Gamal print_serial("cdq Test 2: PASS\n"); 16260cbd5b06SMohammed Gamal } 16270cbd5b06SMohammed Gamal 16287d36db35SAvi Kivity void realmode_start(void) 16297d36db35SAvi Kivity { 16307d36db35SAvi Kivity test_null(); 16317d36db35SAvi Kivity 16327d36db35SAvi Kivity test_shld(); 16337d36db35SAvi Kivity test_push_pop(); 16347d36db35SAvi Kivity test_pusha_popa(); 16357d36db35SAvi Kivity test_mov_imm(); 16367d36db35SAvi Kivity test_cmp_imm(); 16377d36db35SAvi Kivity test_add_imm(); 16387d36db35SAvi Kivity test_sub_imm(); 16397d36db35SAvi Kivity test_xor_imm(); 16407d36db35SAvi Kivity test_io(); 16417d36db35SAvi Kivity test_eflags_insn(); 16427d36db35SAvi Kivity test_jcc_short(); 16437d36db35SAvi Kivity test_jcc_near(); 16447d36db35SAvi Kivity /* test_call() uses short jump so call it after testing jcc */ 16457d36db35SAvi Kivity test_call(); 16467d36db35SAvi Kivity /* long jmp test uses call near so test it after testing call */ 16477d36db35SAvi Kivity test_long_jmp(); 16487d36db35SAvi Kivity test_xchg(); 16497d36db35SAvi Kivity test_iret(); 165096b9ca1eSMohammed Gamal test_int(); 1651fa74f8a6SMohammed Gamal test_imul(); 165259317bd1SMohammed Gamal test_mul(); 16530d4c7614SMohammed Gamal test_div(); 16540d4c7614SMohammed Gamal test_idiv(); 1655eacef4e2SWei Yongjun test_loopcc(); 16566e293cf5SWei Yongjun test_cbw(); 16570cbd5b06SMohammed Gamal test_cwd_cdq(); 1658b274feedSAvi Kivity test_das(); 16597d36db35SAvi Kivity 16607d36db35SAvi Kivity exit(0); 16617d36db35SAvi Kivity } 16627d36db35SAvi Kivity 16637d36db35SAvi Kivity unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff }; 16647d36db35SAvi Kivity 16657d36db35SAvi Kivity struct __attribute__((packed)) { 16667d36db35SAvi Kivity unsigned short limit; 16677d36db35SAvi Kivity void *base; 16687d36db35SAvi Kivity } r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt }; 16697d36db35SAvi Kivity 16707d36db35SAvi Kivity asm( 16717d36db35SAvi Kivity ".section .init \n\t" 16727d36db35SAvi Kivity 16737d36db35SAvi Kivity ".code32 \n\t" 16747d36db35SAvi Kivity 16757d36db35SAvi Kivity "mb_magic = 0x1BADB002 \n\t" 16767d36db35SAvi Kivity "mb_flags = 0x0 \n\t" 16777d36db35SAvi Kivity 16787d36db35SAvi Kivity "# multiboot header \n\t" 16797d36db35SAvi Kivity ".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t" 16807d36db35SAvi Kivity 16817d36db35SAvi Kivity ".globl start \n\t" 16827d36db35SAvi Kivity ".data \n\t" 16837d36db35SAvi Kivity ". = . + 4096 \n\t" 16847d36db35SAvi Kivity "stacktop: \n\t" 16857d36db35SAvi Kivity 16867d36db35SAvi Kivity ".text \n\t" 16877d36db35SAvi Kivity "start: \n\t" 16887d36db35SAvi Kivity "lgdt r_gdt_descr \n\t" 16897d36db35SAvi Kivity "ljmp $8, $1f; 1: \n\t" 16907d36db35SAvi Kivity ".code16gcc \n\t" 16917d36db35SAvi Kivity "mov $16, %eax \n\t" 16927d36db35SAvi Kivity "mov %ax, %ds \n\t" 16937d36db35SAvi Kivity "mov %ax, %es \n\t" 16947d36db35SAvi Kivity "mov %ax, %fs \n\t" 16957d36db35SAvi Kivity "mov %ax, %gs \n\t" 16967d36db35SAvi Kivity "mov %ax, %ss \n\t" 16977d36db35SAvi Kivity "mov %cr0, %eax \n\t" 16987d36db35SAvi Kivity "btc $0, %eax \n\t" 16997d36db35SAvi Kivity "mov %eax, %cr0 \n\t" 17007d36db35SAvi Kivity "ljmp $0, $realmode_entry \n\t" 17017d36db35SAvi Kivity 17027d36db35SAvi Kivity "realmode_entry: \n\t" 17037d36db35SAvi Kivity 17047d36db35SAvi Kivity "xor %ax, %ax \n\t" 17057d36db35SAvi Kivity "mov %ax, %ds \n\t" 17067d36db35SAvi Kivity "mov %ax, %es \n\t" 17077d36db35SAvi Kivity "mov %ax, %ss \n\t" 17087d36db35SAvi Kivity "mov %ax, %fs \n\t" 17097d36db35SAvi Kivity "mov %ax, %gs \n\t" 17107d36db35SAvi Kivity "mov $stacktop, %esp\n\t" 17117d36db35SAvi Kivity "ljmp $0, $realmode_start \n\t" 17127d36db35SAvi Kivity 17137d36db35SAvi Kivity ".code16gcc \n\t" 17147d36db35SAvi Kivity ); 1715