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