1f366255fSPaolo Bonzini #ifndef USE_SERIAL 2f366255fSPaolo Bonzini #define USE_SERIAL 3f366255fSPaolo Bonzini #endif 4f366255fSPaolo Bonzini 547086996SBill Wendling #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0])) 647086996SBill Wendling 77d36db35SAvi Kivity asm(".code16gcc"); 87d36db35SAvi Kivity 97d36db35SAvi Kivity typedef unsigned char u8; 107d36db35SAvi Kivity typedef unsigned short u16; 117d36db35SAvi Kivity typedef unsigned u32; 127d36db35SAvi Kivity typedef unsigned long long u64; 137d36db35SAvi Kivity 14bd62e289SBill Wendling #ifndef NULL 15bd62e289SBill Wendling #define NULL ((void*)0) 16bd62e289SBill Wendling #endif 17bd62e289SBill Wendling 182e3f9f1fSThomas Huth void realmode_start(void); 197d36db35SAvi Kivity void test_function(void); 207d36db35SAvi Kivity 217d36db35SAvi Kivity asm( 227d36db35SAvi Kivity "test_function: \n\t" 237d36db35SAvi Kivity "mov $0x1234, %eax \n\t" 247d36db35SAvi Kivity "ret" 257d36db35SAvi Kivity ); 267d36db35SAvi Kivity 277d36db35SAvi Kivity static int strlen(const char *str) 287d36db35SAvi Kivity { 297d36db35SAvi Kivity int n; 307d36db35SAvi Kivity 317d36db35SAvi Kivity for (n = 0; *str; ++str) 327d36db35SAvi Kivity ++n; 337d36db35SAvi Kivity return n; 347d36db35SAvi Kivity } 357d36db35SAvi Kivity 36f366255fSPaolo Bonzini static void outb(u8 data, u16 port) 37f366255fSPaolo Bonzini { 38f366255fSPaolo Bonzini asm volatile("out %0, %1" : : "a"(data), "d"(port)); 39f366255fSPaolo Bonzini } 40f366255fSPaolo Bonzini 41f366255fSPaolo Bonzini #ifdef USE_SERIAL 42f366255fSPaolo Bonzini static int serial_iobase = 0x3f8; 43f366255fSPaolo Bonzini static int serial_inited = 0; 44f366255fSPaolo Bonzini 45f366255fSPaolo Bonzini static u8 inb(u16 port) 46f366255fSPaolo Bonzini { 47f366255fSPaolo Bonzini u8 data; 48f366255fSPaolo Bonzini asm volatile("in %1, %0" : "=a"(data) : "d"(port)); 49f366255fSPaolo Bonzini return data; 50f366255fSPaolo Bonzini } 51f366255fSPaolo Bonzini 52f366255fSPaolo Bonzini static void serial_outb(char ch) 53f366255fSPaolo Bonzini { 54f366255fSPaolo Bonzini u8 lsr; 55f366255fSPaolo Bonzini 56f366255fSPaolo Bonzini do { 57f366255fSPaolo Bonzini lsr = inb(serial_iobase + 0x05); 58f366255fSPaolo Bonzini } while (!(lsr & 0x20)); 59f366255fSPaolo Bonzini 60f366255fSPaolo Bonzini outb(ch, serial_iobase + 0x00); 61f366255fSPaolo Bonzini } 62f366255fSPaolo Bonzini 63f366255fSPaolo Bonzini static void serial_init(void) 64f366255fSPaolo Bonzini { 65f366255fSPaolo Bonzini u8 lcr; 66f366255fSPaolo Bonzini 67f366255fSPaolo Bonzini /* set DLAB */ 68f366255fSPaolo Bonzini lcr = inb(serial_iobase + 0x03); 69f366255fSPaolo Bonzini lcr |= 0x80; 70f366255fSPaolo Bonzini outb(lcr, serial_iobase + 0x03); 71f366255fSPaolo Bonzini 72f366255fSPaolo Bonzini /* set baud rate to 115200 */ 73f366255fSPaolo Bonzini outb(0x01, serial_iobase + 0x00); 74f366255fSPaolo Bonzini outb(0x00, serial_iobase + 0x01); 75f366255fSPaolo Bonzini 76f366255fSPaolo Bonzini /* clear DLAB */ 77f366255fSPaolo Bonzini lcr = inb(serial_iobase + 0x03); 78f366255fSPaolo Bonzini lcr &= ~0x80; 79f366255fSPaolo Bonzini outb(lcr, serial_iobase + 0x03); 80*c83858a4SNadav Amit 81*c83858a4SNadav Amit /* IER: disable interrupts */ 82*c83858a4SNadav Amit outb(0x00, serial_iobase + 0x01); 83*c83858a4SNadav Amit /* LCR: 8 bits, no parity, one stop bit */ 84*c83858a4SNadav Amit outb(0x03, serial_iobase + 0x03); 85*c83858a4SNadav Amit /* FCR: disable FIFO queues */ 86*c83858a4SNadav Amit outb(0x00, serial_iobase + 0x02); 87*c83858a4SNadav Amit /* MCR: RTS, DTR on */ 88*c83858a4SNadav Amit outb(0x03, serial_iobase + 0x04); 89f366255fSPaolo Bonzini } 90f366255fSPaolo Bonzini #endif 91f366255fSPaolo Bonzini 927d36db35SAvi Kivity static void print_serial(const char *buf) 937d36db35SAvi Kivity { 947d36db35SAvi Kivity unsigned long len = strlen(buf); 95f366255fSPaolo Bonzini #ifdef USE_SERIAL 96f366255fSPaolo Bonzini unsigned long i; 97f366255fSPaolo Bonzini if (!serial_inited) { 98f366255fSPaolo Bonzini serial_init(); 99f366255fSPaolo Bonzini serial_inited = 1; 100f366255fSPaolo Bonzini } 1017d36db35SAvi Kivity 102f366255fSPaolo Bonzini for (i = 0; i < len; i++) { 103f366255fSPaolo Bonzini serial_outb(buf[i]); 104f366255fSPaolo Bonzini } 105f366255fSPaolo Bonzini #else 1065edbb9aeSPaolo Bonzini asm volatile ("addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1)); 107f366255fSPaolo Bonzini #endif 1087d36db35SAvi Kivity } 1097d36db35SAvi Kivity 110b5105e8bSPaolo Bonzini static void print_serial_u32(u32 value) 111b5105e8bSPaolo Bonzini { 112b5105e8bSPaolo Bonzini char n[12], *p; 113b5105e8bSPaolo Bonzini p = &n[11]; 114b5105e8bSPaolo Bonzini *p = 0; 115b5105e8bSPaolo Bonzini do { 116b5105e8bSPaolo Bonzini *--p = '0' + (value % 10); 117b5105e8bSPaolo Bonzini value /= 10; 118b5105e8bSPaolo Bonzini } while (value > 0); 119b5105e8bSPaolo Bonzini print_serial(p); 120b5105e8bSPaolo Bonzini } 121b5105e8bSPaolo Bonzini 122b393fe28SNadav Amit static int failed; 123b393fe28SNadav Amit 1247d36db35SAvi Kivity static void exit(int code) 1257d36db35SAvi Kivity { 126f366255fSPaolo Bonzini outb(code, 0xf4); 1273b9b2d55SNadav Amit 1283b9b2d55SNadav Amit while (1) { 1293b9b2d55SNadav Amit asm volatile("hlt" ::: "memory"); 1303b9b2d55SNadav Amit } 1317d36db35SAvi Kivity } 1327d36db35SAvi Kivity 1337d36db35SAvi Kivity struct regs { 1347d36db35SAvi Kivity u32 eax, ebx, ecx, edx; 1357d36db35SAvi Kivity u32 esi, edi, esp, ebp; 1367d36db35SAvi Kivity u32 eip, eflags; 1377d36db35SAvi Kivity }; 1387d36db35SAvi Kivity 139975ca087SPeter Feiner struct table_descr { 140975ca087SPeter Feiner u16 limit; 141975ca087SPeter Feiner void *base; 142975ca087SPeter Feiner } __attribute__((packed)); 143975ca087SPeter Feiner 1447d36db35SAvi Kivity static u64 gdt[] = { 1457d36db35SAvi Kivity 0, 1467d36db35SAvi Kivity 0x00cf9b000000ffffull, // flat 32-bit code segment 1477d36db35SAvi Kivity 0x00cf93000000ffffull, // flat 32-bit data segment 1487d36db35SAvi Kivity }; 1497d36db35SAvi Kivity 150975ca087SPeter Feiner static struct table_descr gdt_descr = { 1517d36db35SAvi Kivity sizeof(gdt) - 1, 1527d36db35SAvi Kivity gdt, 1537d36db35SAvi Kivity }; 1547d36db35SAvi Kivity 155d4dc402cSAvi Kivity struct insn_desc { 156d4dc402cSAvi Kivity u16 ptr; 157d4dc402cSAvi Kivity u16 len; 158d4dc402cSAvi Kivity }; 159d4dc402cSAvi Kivity 160bd62e289SBill Wendling struct { 161bd62e289SBill Wendling u32 stack[128]; 162bd62e289SBill Wendling char top[]; 163bd62e289SBill Wendling } tmp_stack; 164bd62e289SBill Wendling 16518253fdeSAvi Kivity static struct regs inregs, outregs; 16618253fdeSAvi Kivity 167bd62e289SBill Wendling static inline void init_inregs(struct regs *regs) 168bd62e289SBill Wendling { 169bd62e289SBill Wendling inregs = (struct regs){ 0 }; 170bd62e289SBill Wendling if (regs) 171bd62e289SBill Wendling inregs = *regs; 172bd62e289SBill Wendling if (!inregs.esp) 173bd62e289SBill Wendling inregs.esp = (unsigned long)&tmp_stack.top; 174bd62e289SBill Wendling } 175bd62e289SBill Wendling 17618253fdeSAvi Kivity static void exec_in_big_real_mode(struct insn_desc *insn) 1777d36db35SAvi Kivity { 1787d36db35SAvi Kivity unsigned long tmp; 1797d36db35SAvi Kivity static struct regs save; 1807d36db35SAvi Kivity int i; 1817d36db35SAvi Kivity extern u8 test_insn[], test_insn_end[]; 1827d36db35SAvi Kivity 183d4dc402cSAvi Kivity for (i = 0; i < insn->len; ++i) 184d4dc402cSAvi Kivity test_insn[i] = ((u8 *)(unsigned long)insn->ptr)[i]; 1857d36db35SAvi Kivity for (; i < test_insn_end - test_insn; ++i) 1867d36db35SAvi Kivity test_insn[i] = 0x90; // nop 1877d36db35SAvi Kivity 18818253fdeSAvi Kivity save = inregs; 1897d36db35SAvi Kivity asm volatile( 1907d36db35SAvi Kivity "lgdtl %[gdt_descr] \n\t" 1917d36db35SAvi Kivity "mov %%cr0, %[tmp] \n\t" 1927d36db35SAvi Kivity "or $1, %[tmp] \n\t" 1937d36db35SAvi Kivity "mov %[tmp], %%cr0 \n\t" 1947d36db35SAvi Kivity "mov %[bigseg], %%gs \n\t" 1957d36db35SAvi Kivity "and $-2, %[tmp] \n\t" 1967d36db35SAvi Kivity "mov %[tmp], %%cr0 \n\t" 1977d36db35SAvi Kivity 198eb6687a2SBill Wendling /* Save ES, because it is clobbered by some tests. */ 199eb6687a2SBill Wendling "pushw %%es \n\t" 200eb6687a2SBill Wendling 20132001692SAvi Kivity "pushw %[save]+36; popfw \n\t" 2027d36db35SAvi Kivity "xchg %%eax, %[save]+0 \n\t" 2037d36db35SAvi Kivity "xchg %%ebx, %[save]+4 \n\t" 2047d36db35SAvi Kivity "xchg %%ecx, %[save]+8 \n\t" 2057d36db35SAvi Kivity "xchg %%edx, %[save]+12 \n\t" 2067d36db35SAvi Kivity "xchg %%esi, %[save]+16 \n\t" 2077d36db35SAvi Kivity "xchg %%edi, %[save]+20 \n\t" 2087d36db35SAvi Kivity "xchg %%esp, %[save]+24 \n\t" 2097d36db35SAvi Kivity "xchg %%ebp, %[save]+28 \n\t" 2107d36db35SAvi Kivity 2117d36db35SAvi Kivity "test_insn: . = . + 32\n\t" 2127d36db35SAvi Kivity "test_insn_end: \n\t" 2137d36db35SAvi Kivity 2147d36db35SAvi Kivity "xchg %%eax, %[save]+0 \n\t" 2157d36db35SAvi Kivity "xchg %%ebx, %[save]+4 \n\t" 2167d36db35SAvi Kivity "xchg %%ecx, %[save]+8 \n\t" 2177d36db35SAvi Kivity "xchg %%edx, %[save]+12 \n\t" 2187d36db35SAvi Kivity "xchg %%esi, %[save]+16 \n\t" 2197d36db35SAvi Kivity "xchg %%edi, %[save]+20 \n\t" 2207d36db35SAvi Kivity "xchg %%esp, %[save]+24 \n\t" 2217d36db35SAvi Kivity "xchg %%ebp, %[save]+28 \n\t" 2227d36db35SAvi Kivity 2237d36db35SAvi Kivity /* Save EFLAGS in outregs*/ 2247d36db35SAvi Kivity "pushfl \n\t" 2257d36db35SAvi Kivity "popl %[save]+36 \n\t" 2267d36db35SAvi Kivity 227eb6687a2SBill Wendling /* Restore ES for future rep string operations. */ 228eb6687a2SBill Wendling "popw %%es \n\t" 229eb6687a2SBill Wendling 2305edbb9aeSPaolo Bonzini /* Restore DF for the harness code */ 2315edbb9aeSPaolo Bonzini "cld\n\t" 2327d36db35SAvi Kivity "xor %[tmp], %[tmp] \n\t" 2337d36db35SAvi Kivity "mov %[tmp], %%gs \n\t" 2347d36db35SAvi Kivity : [tmp]"=&r"(tmp), [save]"+m"(save) 2357d36db35SAvi Kivity : [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16) 2367d36db35SAvi Kivity : "cc", "memory" 2377d36db35SAvi Kivity ); 23818253fdeSAvi Kivity outregs = save; 2397d36db35SAvi Kivity } 2407d36db35SAvi Kivity 2417d36db35SAvi Kivity #define R_AX 1 2427d36db35SAvi Kivity #define R_BX 2 2437d36db35SAvi Kivity #define R_CX 4 2447d36db35SAvi Kivity #define R_DX 8 2457d36db35SAvi Kivity #define R_SI 16 2467d36db35SAvi Kivity #define R_DI 32 2477d36db35SAvi Kivity #define R_SP 64 2487d36db35SAvi Kivity #define R_BP 128 2497d36db35SAvi Kivity 2502e3f9f1fSThomas Huth static int regs_equal(int ignore) 2517d36db35SAvi Kivity { 25218253fdeSAvi Kivity const u32 *p1 = &inregs.eax, *p2 = &outregs.eax; // yuck 2537d36db35SAvi Kivity int i; 2547d36db35SAvi Kivity 2557d36db35SAvi Kivity for (i = 0; i < 8; ++i) 2567d36db35SAvi Kivity if (!(ignore & (1 << i)) && p1[i] != p2[i]) 2577d36db35SAvi Kivity return 0; 2587d36db35SAvi Kivity return 1; 2597d36db35SAvi Kivity } 2607d36db35SAvi Kivity 2616055ea1fSAvi Kivity static void report(const char *name, u16 regs_ignore, _Bool ok) 26281050840SAvi Kivity { 2636055ea1fSAvi Kivity if (!regs_equal(regs_ignore)) { 2646055ea1fSAvi Kivity ok = 0; 2656055ea1fSAvi Kivity } 26681050840SAvi Kivity print_serial(ok ? "PASS: " : "FAIL: "); 26781050840SAvi Kivity print_serial(name); 26881050840SAvi Kivity print_serial("\n"); 269b393fe28SNadav Amit if (!ok) 270b393fe28SNadav Amit failed = 1; 27181050840SAvi Kivity } 27281050840SAvi Kivity 2737d36db35SAvi Kivity #define MK_INSN(name, str) \ 2747d36db35SAvi Kivity asm ( \ 275d4dc402cSAvi Kivity ".pushsection .data.insn \n\t" \ 276d4dc402cSAvi Kivity "insn_" #name ": \n\t" \ 277d4dc402cSAvi Kivity ".word 1001f, 1002f - 1001f \n\t" \ 278d4dc402cSAvi Kivity ".popsection \n\t" \ 279d4dc402cSAvi Kivity ".pushsection .text.insn, \"ax\" \n\t" \ 280d4dc402cSAvi Kivity "1001: \n\t" \ 281d4dc402cSAvi Kivity "insn_code_" #name ": " str " \n\t" \ 282d4dc402cSAvi Kivity "1002: \n\t" \ 283d4dc402cSAvi Kivity ".popsection" \ 2847d36db35SAvi Kivity ); \ 285d4dc402cSAvi Kivity extern struct insn_desc insn_##name; 2867d36db35SAvi Kivity 2872e3f9f1fSThomas Huth static void test_xchg(void) 2887d36db35SAvi Kivity { 2897d36db35SAvi Kivity MK_INSN(xchg_test1, "xchg %eax,%eax\n\t"); 2907d36db35SAvi Kivity MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t"); 2917d36db35SAvi Kivity MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t"); 2927d36db35SAvi Kivity MK_INSN(xchg_test4, "xchg %eax,%edx\n\t"); 2937d36db35SAvi Kivity MK_INSN(xchg_test5, "xchg %eax,%esi\n\t"); 2947d36db35SAvi Kivity MK_INSN(xchg_test6, "xchg %eax,%edi\n\t"); 2957d36db35SAvi Kivity MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t"); 2967d36db35SAvi Kivity MK_INSN(xchg_test8, "xchg %eax,%esp\n\t"); 2977d36db35SAvi Kivity 29818253fdeSAvi Kivity inregs = (struct regs){ .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}; 2997d36db35SAvi Kivity 30018253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test1); 3016055ea1fSAvi Kivity report("xchg 1", 0, 1); 30218253fdeSAvi Kivity 30318253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test2); 3046055ea1fSAvi Kivity report("xchg 2", R_AX | R_BX, 3056055ea1fSAvi Kivity outregs.eax == inregs.ebx && outregs.ebx == inregs.eax); 3067d36db35SAvi Kivity 30718253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test3); 3086055ea1fSAvi Kivity report("xchg 3", R_AX | R_CX, 3096055ea1fSAvi Kivity outregs.eax == inregs.ecx && outregs.ecx == inregs.eax); 3107d36db35SAvi Kivity 31118253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test4); 3126055ea1fSAvi Kivity report("xchg 4", R_AX | R_DX, 3136055ea1fSAvi Kivity outregs.eax == inregs.edx && outregs.edx == inregs.eax); 3147d36db35SAvi Kivity 31518253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test5); 3166055ea1fSAvi Kivity report("xchg 5", R_AX | R_SI, 3176055ea1fSAvi Kivity outregs.eax == inregs.esi && outregs.esi == inregs.eax); 3187d36db35SAvi Kivity 31918253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test6); 3206055ea1fSAvi Kivity report("xchg 6", R_AX | R_DI, 3216055ea1fSAvi Kivity outregs.eax == inregs.edi && outregs.edi == inregs.eax); 3227d36db35SAvi Kivity 32318253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test7); 3246055ea1fSAvi Kivity report("xchg 7", R_AX | R_BP, 3256055ea1fSAvi Kivity outregs.eax == inregs.ebp && outregs.ebp == inregs.eax); 3267d36db35SAvi Kivity 32718253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test8); 3286055ea1fSAvi Kivity report("xchg 8", R_AX | R_SP, 3296055ea1fSAvi Kivity outregs.eax == inregs.esp && outregs.esp == inregs.eax); 3307d36db35SAvi Kivity } 3317d36db35SAvi Kivity 3322e3f9f1fSThomas Huth static void test_shld(void) 3337d36db35SAvi Kivity { 3347d36db35SAvi Kivity MK_INSN(shld_test, "shld $8,%edx,%eax\n\t"); 3357d36db35SAvi Kivity 336bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0xbe, .edx = 0xef000000 }); 337bd62e289SBill Wendling 33818253fdeSAvi Kivity exec_in_big_real_mode(&insn_shld_test); 3396055ea1fSAvi Kivity report("shld", ~0, outregs.eax == 0xbeef); 3407d36db35SAvi Kivity } 3417d36db35SAvi Kivity 3422e3f9f1fSThomas Huth static void test_mov_imm(void) 3437d36db35SAvi Kivity { 3447d36db35SAvi Kivity MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax"); 3457d36db35SAvi Kivity MK_INSN(mov_r16_imm_1, "mov $1234, %ax"); 3467d36db35SAvi Kivity MK_INSN(mov_r8_imm_1, "mov $0x12, %ah"); 3477d36db35SAvi Kivity MK_INSN(mov_r8_imm_2, "mov $0x34, %al"); 3487d36db35SAvi Kivity MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t"); 3497d36db35SAvi Kivity 350bd62e289SBill Wendling init_inregs(NULL); 35118253fdeSAvi Kivity 35218253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r16_imm_1); 3536055ea1fSAvi Kivity report("mov 1", R_AX, outregs.eax == 1234); 3547d36db35SAvi Kivity 3557d36db35SAvi Kivity /* test mov $imm, %eax */ 35618253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r32_imm_1); 3576055ea1fSAvi Kivity report("mov 2", R_AX, outregs.eax == 1234567890); 3587d36db35SAvi Kivity 3597d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 36018253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r8_imm_1); 3616055ea1fSAvi Kivity report("mov 3", R_AX, outregs.eax == 0x1200); 3627d36db35SAvi Kivity 36318253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r8_imm_2); 3646055ea1fSAvi Kivity report("mov 4", R_AX, outregs.eax == 0x34); 3657d36db35SAvi Kivity 36618253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r8_imm_3); 3676055ea1fSAvi Kivity report("mov 5", R_AX, outregs.eax == 0x1234); 3687d36db35SAvi Kivity } 3697d36db35SAvi Kivity 3702e3f9f1fSThomas Huth static void test_sub_imm(void) 3717d36db35SAvi Kivity { 3727d36db35SAvi Kivity MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t"); 3737d36db35SAvi Kivity MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t"); 3747d36db35SAvi Kivity MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t"); 3757d36db35SAvi Kivity MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t"); 3767d36db35SAvi Kivity 377bd62e289SBill Wendling init_inregs(NULL); 37818253fdeSAvi Kivity 37918253fdeSAvi Kivity exec_in_big_real_mode(&insn_sub_r16_imm_1); 3806055ea1fSAvi Kivity report("sub 1", R_AX, outregs.eax == 1224); 3817d36db35SAvi Kivity 3827d36db35SAvi Kivity /* test mov $imm, %eax */ 38318253fdeSAvi Kivity exec_in_big_real_mode(&insn_sub_r32_imm_1); 3846055ea1fSAvi Kivity report("sub 2", R_AX, outregs.eax == 1234567880); 3857d36db35SAvi Kivity 3867d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 38718253fdeSAvi Kivity exec_in_big_real_mode(&insn_sub_r8_imm_1); 3886055ea1fSAvi Kivity report("sub 3", R_AX, outregs.eax == 0x0200); 3897d36db35SAvi Kivity 39018253fdeSAvi Kivity exec_in_big_real_mode(&insn_sub_r8_imm_2); 3916055ea1fSAvi Kivity report("sub 4", R_AX, outregs.eax == 0x24); 3927d36db35SAvi Kivity } 3937d36db35SAvi Kivity 3942e3f9f1fSThomas Huth static void test_xor_imm(void) 3957d36db35SAvi Kivity { 3967d36db35SAvi Kivity MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t"); 3977d36db35SAvi Kivity MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t"); 3987d36db35SAvi Kivity MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t"); 3997d36db35SAvi Kivity MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t"); 4007d36db35SAvi Kivity 401bd62e289SBill Wendling init_inregs(NULL); 40218253fdeSAvi Kivity 40318253fdeSAvi Kivity exec_in_big_real_mode(&insn_xor_r16_imm_1); 4046055ea1fSAvi Kivity report("xor 1", R_AX, outregs.eax == 0); 4057d36db35SAvi Kivity 4067d36db35SAvi Kivity /* test mov $imm, %eax */ 40718253fdeSAvi Kivity exec_in_big_real_mode(&insn_xor_r32_imm_1); 4086055ea1fSAvi Kivity report("xor 2", R_AX, outregs.eax == 0); 4097d36db35SAvi Kivity 4107d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 41118253fdeSAvi Kivity exec_in_big_real_mode(&insn_xor_r8_imm_1); 4126055ea1fSAvi Kivity report("xor 3", R_AX, outregs.eax == 0); 4137d36db35SAvi Kivity 41418253fdeSAvi Kivity exec_in_big_real_mode(&insn_xor_r8_imm_2); 4156055ea1fSAvi Kivity report("xor 4", R_AX, outregs.eax == 0); 4167d36db35SAvi Kivity } 4177d36db35SAvi Kivity 4182e3f9f1fSThomas Huth static void test_cmp_imm(void) 4197d36db35SAvi Kivity { 4207d36db35SAvi Kivity MK_INSN(cmp_test1, "mov $0x34, %al\n\t" 4217d36db35SAvi Kivity "cmp $0x34, %al\n\t"); 4227d36db35SAvi Kivity MK_INSN(cmp_test2, "mov $0x34, %al\n\t" 4237d36db35SAvi Kivity "cmp $0x39, %al\n\t"); 4247d36db35SAvi Kivity MK_INSN(cmp_test3, "mov $0x34, %al\n\t" 4257d36db35SAvi Kivity "cmp $0x24, %al\n\t"); 4267d36db35SAvi Kivity 427bd62e289SBill Wendling init_inregs(NULL); 42818253fdeSAvi Kivity 4297d36db35SAvi Kivity /* test cmp imm8 with AL */ 4307d36db35SAvi Kivity /* ZF: (bit 6) Zero Flag becomes 1 if an operation results 4317d36db35SAvi Kivity * in a 0 writeback, or 0 register 4327d36db35SAvi Kivity */ 43318253fdeSAvi Kivity exec_in_big_real_mode(&insn_cmp_test1); 4346055ea1fSAvi Kivity report("cmp 1", ~0, (outregs.eflags & (1<<6)) == (1<<6)); 4357d36db35SAvi Kivity 43618253fdeSAvi Kivity exec_in_big_real_mode(&insn_cmp_test2); 4376055ea1fSAvi Kivity report("cmp 2", ~0, (outregs.eflags & (1<<6)) == 0); 4387d36db35SAvi Kivity 43918253fdeSAvi Kivity exec_in_big_real_mode(&insn_cmp_test3); 4406055ea1fSAvi Kivity report("cmp 3", ~0, (outregs.eflags & (1<<6)) == 0); 4417d36db35SAvi Kivity } 4427d36db35SAvi Kivity 4432e3f9f1fSThomas Huth static void test_add_imm(void) 4447d36db35SAvi Kivity { 4457d36db35SAvi Kivity MK_INSN(add_test1, "mov $0x43211234, %eax \n\t" 4467d36db35SAvi Kivity "add $0x12344321, %eax \n\t"); 4477d36db35SAvi Kivity MK_INSN(add_test2, "mov $0x12, %eax \n\t" 4487d36db35SAvi Kivity "add $0x21, %al\n\t"); 4497d36db35SAvi Kivity 450bd62e289SBill Wendling init_inregs(NULL); 45118253fdeSAvi Kivity 45218253fdeSAvi Kivity exec_in_big_real_mode(&insn_add_test1); 4536055ea1fSAvi Kivity report("add 1", ~0, outregs.eax == 0x55555555); 4547d36db35SAvi Kivity 45518253fdeSAvi Kivity exec_in_big_real_mode(&insn_add_test2); 4566055ea1fSAvi Kivity report("add 2", ~0, outregs.eax == 0x33); 4577d36db35SAvi Kivity } 4587d36db35SAvi Kivity 4592e3f9f1fSThomas Huth static void test_eflags_insn(void) 4607d36db35SAvi Kivity { 4617d36db35SAvi Kivity MK_INSN(clc, "clc"); 462b3261e48SMohammed Gamal MK_INSN(stc, "stc"); 4637d36db35SAvi Kivity MK_INSN(cli, "cli"); 4647d36db35SAvi Kivity MK_INSN(sti, "sti"); 4657d36db35SAvi Kivity MK_INSN(cld, "cld"); 4667d36db35SAvi Kivity MK_INSN(std, "std"); 4677d36db35SAvi Kivity 468bd62e289SBill Wendling init_inregs(NULL); 46918253fdeSAvi Kivity 47018253fdeSAvi Kivity exec_in_big_real_mode(&insn_clc); 4716055ea1fSAvi Kivity report("clc", ~0, (outregs.eflags & 1) == 0); 4727d36db35SAvi Kivity 47318253fdeSAvi Kivity exec_in_big_real_mode(&insn_stc); 4746055ea1fSAvi Kivity report("stc", ~0, (outregs.eflags & 1) == 1); 475b3261e48SMohammed Gamal 47618253fdeSAvi Kivity exec_in_big_real_mode(&insn_cli); 4776055ea1fSAvi Kivity report("cli", ~0, !(outregs.eflags & (1 << 9))); 4787d36db35SAvi Kivity 47918253fdeSAvi Kivity exec_in_big_real_mode(&insn_sti); 4806055ea1fSAvi Kivity report("sti", ~0, outregs.eflags & (1 << 9)); 4817d36db35SAvi Kivity 48218253fdeSAvi Kivity exec_in_big_real_mode(&insn_cld); 4836055ea1fSAvi Kivity report("cld", ~0, !(outregs.eflags & (1 << 10))); 4847d36db35SAvi Kivity 48518253fdeSAvi Kivity exec_in_big_real_mode(&insn_std); 4866055ea1fSAvi Kivity report("std", ~0, (outregs.eflags & (1 << 10))); 4877d36db35SAvi Kivity } 4887d36db35SAvi Kivity 4892e3f9f1fSThomas Huth static void test_io(void) 4907d36db35SAvi Kivity { 4917d36db35SAvi Kivity MK_INSN(io_test1, "mov $0xff, %al \n\t" 4927d36db35SAvi Kivity "out %al, $0xe0 \n\t" 4937d36db35SAvi Kivity "mov $0x00, %al \n\t" 4947d36db35SAvi Kivity "in $0xe0, %al \n\t"); 4957d36db35SAvi Kivity MK_INSN(io_test2, "mov $0xffff, %ax \n\t" 4967d36db35SAvi Kivity "out %ax, $0xe0 \n\t" 4977d36db35SAvi Kivity "mov $0x0000, %ax \n\t" 4987d36db35SAvi Kivity "in $0xe0, %ax \n\t"); 4997d36db35SAvi Kivity MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t" 5007d36db35SAvi Kivity "out %eax, $0xe0 \n\t" 5017d36db35SAvi Kivity "mov $0x000000, %eax \n\t" 5027d36db35SAvi Kivity "in $0xe0, %eax \n\t"); 5037d36db35SAvi Kivity MK_INSN(io_test4, "mov $0xe0, %dx \n\t" 5047d36db35SAvi Kivity "mov $0xff, %al \n\t" 5057d36db35SAvi Kivity "out %al, %dx \n\t" 5067d36db35SAvi Kivity "mov $0x00, %al \n\t" 5077d36db35SAvi Kivity "in %dx, %al \n\t"); 5087d36db35SAvi Kivity MK_INSN(io_test5, "mov $0xe0, %dx \n\t" 5097d36db35SAvi Kivity "mov $0xffff, %ax \n\t" 5107d36db35SAvi Kivity "out %ax, %dx \n\t" 5117d36db35SAvi Kivity "mov $0x0000, %ax \n\t" 5127d36db35SAvi Kivity "in %dx, %ax \n\t"); 5137d36db35SAvi Kivity MK_INSN(io_test6, "mov $0xe0, %dx \n\t" 5147d36db35SAvi Kivity "mov $0xffffffff, %eax \n\t" 5157d36db35SAvi Kivity "out %eax, %dx \n\t" 5167d36db35SAvi Kivity "mov $0x00000000, %eax \n\t" 5177d36db35SAvi Kivity "in %dx, %eax \n\t"); 5187d36db35SAvi Kivity 519bd62e289SBill Wendling init_inregs(NULL); 52018253fdeSAvi Kivity 52118253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test1); 5226055ea1fSAvi Kivity report("pio 1", R_AX, outregs.eax == 0xff); 5237d36db35SAvi Kivity 52418253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test2); 5256055ea1fSAvi Kivity report("pio 2", R_AX, outregs.eax == 0xffff); 5267d36db35SAvi Kivity 52718253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test3); 5286055ea1fSAvi Kivity report("pio 3", R_AX, outregs.eax == 0xffffffff); 5297d36db35SAvi Kivity 53018253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test4); 5316055ea1fSAvi Kivity report("pio 4", R_AX|R_DX, outregs.eax == 0xff); 5327d36db35SAvi Kivity 53318253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test5); 5346055ea1fSAvi Kivity report("pio 5", R_AX|R_DX, outregs.eax == 0xffff); 5357d36db35SAvi Kivity 53618253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test6); 5376055ea1fSAvi Kivity report("pio 6", R_AX|R_DX, outregs.eax == 0xffffffff); 5387d36db35SAvi Kivity } 5397d36db35SAvi Kivity 540c0b7268dSAvi Kivity asm ("retf: lretw"); 5412e3f9f1fSThomas Huth extern void retf(void); 542c0b7268dSAvi Kivity 5434f66bc86SBruce Rogers asm ("retf_imm: lretw $10"); 5442e3f9f1fSThomas Huth extern void retf_imm(void); 5454f66bc86SBruce Rogers 5462e3f9f1fSThomas Huth static void test_call(void) 5477d36db35SAvi Kivity { 548c0b7268dSAvi Kivity u32 addr; 5497d36db35SAvi Kivity 5507d36db35SAvi Kivity MK_INSN(call1, "mov $test_function, %eax \n\t" 5517d36db35SAvi Kivity "call *%eax\n\t"); 5527d36db35SAvi Kivity MK_INSN(call_near1, "jmp 2f\n\t" 5537d36db35SAvi Kivity "1: mov $0x1234, %eax\n\t" 5547d36db35SAvi Kivity "ret\n\t" 5557d36db35SAvi Kivity "2: call 1b\t"); 5567d36db35SAvi Kivity MK_INSN(call_near2, "call 1f\n\t" 5577d36db35SAvi Kivity "jmp 2f\n\t" 5587d36db35SAvi Kivity "1: mov $0x1234, %eax\n\t" 5597d36db35SAvi Kivity "ret\n\t" 5607d36db35SAvi Kivity "2:\t"); 561c0b7268dSAvi Kivity MK_INSN(call_far1, "lcallw *(%ebx)\n\t"); 562556d2680SWei Yongjun MK_INSN(call_far2, "lcallw $0, $retf\n\t"); 563c6061817SAvi Kivity MK_INSN(ret_imm, "sub $10, %sp; jmp 2f; 1: retw $10; 2: callw 1b"); 5644f66bc86SBruce Rogers MK_INSN(retf_imm, "sub $10, %sp; lcallw $0, $retf_imm"); 5657d36db35SAvi Kivity 566bd62e289SBill Wendling init_inregs(NULL); 567bd62e289SBill Wendling 56818253fdeSAvi Kivity exec_in_big_real_mode(&insn_call1); 5696055ea1fSAvi Kivity report("call 1", R_AX, outregs.eax == 0x1234); 5707d36db35SAvi Kivity 57118253fdeSAvi Kivity exec_in_big_real_mode(&insn_call_near1); 5726055ea1fSAvi Kivity report("call near 1", R_AX, outregs.eax == 0x1234); 5737d36db35SAvi Kivity 57418253fdeSAvi Kivity exec_in_big_real_mode(&insn_call_near2); 5756055ea1fSAvi Kivity report("call near 2", R_AX, outregs.eax == 0x1234); 576c0b7268dSAvi Kivity 577c0b7268dSAvi Kivity addr = (((unsigned)retf >> 4) << 16) | ((unsigned)retf & 0x0f); 578c0b7268dSAvi Kivity inregs.ebx = (unsigned)&addr; 57918253fdeSAvi Kivity exec_in_big_real_mode(&insn_call_far1); 5806055ea1fSAvi Kivity report("call far 1", 0, 1); 581c6061817SAvi Kivity 582556d2680SWei Yongjun exec_in_big_real_mode(&insn_call_far2); 583556d2680SWei Yongjun report("call far 2", 0, 1); 584556d2680SWei Yongjun 58518253fdeSAvi Kivity exec_in_big_real_mode(&insn_ret_imm); 5866055ea1fSAvi Kivity report("ret imm 1", 0, 1); 5874f66bc86SBruce Rogers 5884f66bc86SBruce Rogers exec_in_big_real_mode(&insn_retf_imm); 5894f66bc86SBruce Rogers report("retf imm 1", 0, 1); 5907d36db35SAvi Kivity } 5917d36db35SAvi Kivity 5922e3f9f1fSThomas Huth static void test_jcc_short(void) 5937d36db35SAvi Kivity { 5947d36db35SAvi Kivity MK_INSN(jnz_short1, "jnz 1f\n\t" 5957d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 5967d36db35SAvi Kivity "1:\n\t"); 5977d36db35SAvi Kivity MK_INSN(jnz_short2, "1:\n\t" 5987d36db35SAvi Kivity "cmp $0x1234, %eax\n\t" 5997d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6007d36db35SAvi Kivity "jnz 1b\n\t"); 6017d36db35SAvi Kivity MK_INSN(jmp_short1, "jmp 1f\n\t" 6027d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6037d36db35SAvi Kivity "1:\n\t"); 6047d36db35SAvi Kivity 605bd62e289SBill Wendling init_inregs(NULL); 6067d36db35SAvi Kivity 60718253fdeSAvi Kivity exec_in_big_real_mode(&insn_jnz_short1); 6086055ea1fSAvi Kivity report("jnz short 1", ~0, 1); 60918253fdeSAvi Kivity 61018253fdeSAvi Kivity exec_in_big_real_mode(&insn_jnz_short2); 6116055ea1fSAvi Kivity report("jnz short 2", R_AX, (outregs.eflags & (1 << 6))); 6127d36db35SAvi Kivity 61318253fdeSAvi Kivity exec_in_big_real_mode(&insn_jmp_short1); 6146055ea1fSAvi Kivity report("jmp short 1", ~0, 1); 6157d36db35SAvi Kivity } 6167d36db35SAvi Kivity 6172e3f9f1fSThomas Huth static void test_jcc_near(void) 6187d36db35SAvi Kivity { 6197d36db35SAvi Kivity /* encode near jmp manually. gas will not do it if offsets < 127 byte */ 6207d36db35SAvi Kivity MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t" 6217d36db35SAvi Kivity "mov $0x1234, %eax\n\t"); 6227d36db35SAvi Kivity MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t" 6237d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6247d36db35SAvi Kivity ".byte 0x0f, 0x85, 0xf0, 0xff\n\t"); 6257d36db35SAvi Kivity MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t" 6267d36db35SAvi Kivity "mov $0x1234, %eax\n\t"); 6277d36db35SAvi Kivity 628bd62e289SBill Wendling init_inregs(NULL); 6297d36db35SAvi Kivity 63018253fdeSAvi Kivity exec_in_big_real_mode(&insn_jnz_near1); 6316055ea1fSAvi Kivity report("jnz near 1", 0, 1); 63218253fdeSAvi Kivity 63318253fdeSAvi Kivity exec_in_big_real_mode(&insn_jnz_near2); 6346055ea1fSAvi Kivity report("jnz near 2", R_AX, outregs.eflags & (1 << 6)); 6357d36db35SAvi Kivity 63618253fdeSAvi Kivity exec_in_big_real_mode(&insn_jmp_near1); 6376055ea1fSAvi Kivity report("jmp near 1", 0, 1); 6387d36db35SAvi Kivity } 6397d36db35SAvi Kivity 6402e3f9f1fSThomas Huth static void test_long_jmp(void) 6417d36db35SAvi Kivity { 6427d36db35SAvi Kivity MK_INSN(long_jmp, "call 1f\n\t" 6437d36db35SAvi Kivity "jmp 2f\n\t" 6447d36db35SAvi Kivity "1: jmp $0, $test_function\n\t" 6457d36db35SAvi Kivity "2:\n\t"); 646bd62e289SBill Wendling 647bd62e289SBill Wendling init_inregs(NULL); 648bd62e289SBill Wendling 64918253fdeSAvi Kivity exec_in_big_real_mode(&insn_long_jmp); 6506055ea1fSAvi Kivity report("jmp far 1", R_AX, outregs.eax == 0x1234); 6517d36db35SAvi Kivity } 652fa74f8a6SMohammed Gamal 6532e3f9f1fSThomas Huth static void test_push_pop(void) 6547d36db35SAvi Kivity { 6557d36db35SAvi Kivity MK_INSN(push32, "mov $0x12345678, %eax\n\t" 6567d36db35SAvi Kivity "push %eax\n\t" 6577d36db35SAvi Kivity "pop %ebx\n\t"); 6587d36db35SAvi Kivity MK_INSN(push16, "mov $0x1234, %ax\n\t" 6597d36db35SAvi Kivity "push %ax\n\t" 6607d36db35SAvi Kivity "pop %bx\n\t"); 6617d36db35SAvi Kivity 6627d36db35SAvi Kivity MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten 6637d36db35SAvi Kivity "mov $0x123, %ax\n\t" 6647d36db35SAvi Kivity "mov %ax, %es\n\t" 665231b4c3bSRoman Bolshakov "pushw %es\n\t" 6667d36db35SAvi Kivity "pop %bx \n\t" 6677d36db35SAvi Kivity ); 6687d36db35SAvi Kivity MK_INSN(pop_es, "push %ax\n\t" 669231b4c3bSRoman Bolshakov "popw %es\n\t" 6707d36db35SAvi Kivity "mov %es, %bx\n\t" 6717d36db35SAvi Kivity ); 672231b4c3bSRoman Bolshakov MK_INSN(push_pop_ss, "pushw %ss\n\t" 6737d36db35SAvi Kivity "pushw %ax\n\t" 6747d36db35SAvi Kivity "popw %ss\n\t" 6757d36db35SAvi Kivity "mov %ss, %bx\n\t" 676231b4c3bSRoman Bolshakov "popw %ss\n\t" 6777d36db35SAvi Kivity ); 678231b4c3bSRoman Bolshakov MK_INSN(push_pop_fs, "pushl %fs\n\t" 6797d36db35SAvi Kivity "pushl %eax\n\t" 6807d36db35SAvi Kivity "popl %fs\n\t" 6817d36db35SAvi Kivity "mov %fs, %ebx\n\t" 682231b4c3bSRoman Bolshakov "popl %fs\n\t" 6837d36db35SAvi Kivity ); 68409b657b6SAvi Kivity MK_INSN(push_pop_high_esp_bits, 68509b657b6SAvi Kivity "xor $0x12340000, %esp \n\t" 68609b657b6SAvi Kivity "push %ax; \n\t" 68709b657b6SAvi Kivity "xor $0x12340000, %esp \n\t" 68809b657b6SAvi Kivity "pop %bx"); 6897d36db35SAvi Kivity 690bd62e289SBill Wendling init_inregs(NULL); 69118253fdeSAvi Kivity 69218253fdeSAvi Kivity exec_in_big_real_mode(&insn_push32); 6936055ea1fSAvi Kivity report("push/pop 1", R_AX|R_BX, 6946055ea1fSAvi Kivity outregs.eax == outregs.ebx && outregs.eax == 0x12345678); 6957d36db35SAvi Kivity 69618253fdeSAvi Kivity exec_in_big_real_mode(&insn_push16); 6976055ea1fSAvi Kivity report("push/pop 2", R_AX|R_BX, 6986055ea1fSAvi Kivity outregs.eax == outregs.ebx && outregs.eax == 0x1234); 6997d36db35SAvi Kivity 70018253fdeSAvi Kivity exec_in_big_real_mode(&insn_push_es); 7016055ea1fSAvi Kivity report("push/pop 3", R_AX|R_BX, 7026055ea1fSAvi Kivity outregs.ebx == outregs.eax && outregs.eax == 0x123); 7037d36db35SAvi Kivity 70418253fdeSAvi Kivity exec_in_big_real_mode(&insn_pop_es); 7056055ea1fSAvi Kivity report("push/pop 4", R_AX|R_BX, outregs.ebx == outregs.eax); 7067d36db35SAvi Kivity 70718253fdeSAvi Kivity exec_in_big_real_mode(&insn_push_pop_ss); 7086055ea1fSAvi Kivity report("push/pop 5", R_AX|R_BX, outregs.ebx == outregs.eax); 7097d36db35SAvi Kivity 71018253fdeSAvi Kivity exec_in_big_real_mode(&insn_push_pop_fs); 7116055ea1fSAvi Kivity report("push/pop 6", R_AX|R_BX, outregs.ebx == outregs.eax); 71209b657b6SAvi Kivity 71309b657b6SAvi Kivity inregs.eax = 0x9977; 71409b657b6SAvi Kivity inregs.ebx = 0x7799; 71509b657b6SAvi Kivity exec_in_big_real_mode(&insn_push_pop_high_esp_bits); 71609b657b6SAvi Kivity report("push/pop with high bits set in %esp", R_BX, outregs.ebx == 0x9977); 7177d36db35SAvi Kivity } 7187d36db35SAvi Kivity 7192e3f9f1fSThomas Huth static void test_null(void) 7207d36db35SAvi Kivity { 721d4dc402cSAvi Kivity MK_INSN(null, ""); 722d4dc402cSAvi Kivity 723bd62e289SBill Wendling init_inregs(NULL); 72418253fdeSAvi Kivity 72518253fdeSAvi Kivity exec_in_big_real_mode(&insn_null); 7266055ea1fSAvi Kivity report("null", 0, 1); 7277d36db35SAvi Kivity } 7287d36db35SAvi Kivity 7292e3f9f1fSThomas Huth static void test_pusha_popa(void) 7307d36db35SAvi Kivity { 7317d36db35SAvi Kivity MK_INSN(pusha, "pusha\n\t" 7327d36db35SAvi Kivity "pop %edi\n\t" 7337d36db35SAvi Kivity "pop %esi\n\t" 7347d36db35SAvi Kivity "pop %ebp\n\t" 7357d36db35SAvi Kivity "add $4, %esp\n\t" 7367d36db35SAvi Kivity "pop %ebx\n\t" 7377d36db35SAvi Kivity "pop %edx\n\t" 7387d36db35SAvi Kivity "pop %ecx\n\t" 7397d36db35SAvi Kivity "pop %eax\n\t" 7407d36db35SAvi Kivity ); 7417d36db35SAvi Kivity 7427d36db35SAvi Kivity MK_INSN(popa, "push %eax\n\t" 7437d36db35SAvi Kivity "push %ecx\n\t" 7447d36db35SAvi Kivity "push %edx\n\t" 7457d36db35SAvi Kivity "push %ebx\n\t" 7467d36db35SAvi Kivity "push %esp\n\t" 7477d36db35SAvi Kivity "push %ebp\n\t" 7487d36db35SAvi Kivity "push %esi\n\t" 7497d36db35SAvi Kivity "push %edi\n\t" 7507d36db35SAvi Kivity "popa\n\t" 7517d36db35SAvi Kivity ); 7527d36db35SAvi Kivity 753bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6 }); 7547d36db35SAvi Kivity 75518253fdeSAvi Kivity exec_in_big_real_mode(&insn_pusha); 7566055ea1fSAvi Kivity report("pusha/popa 1", 0, 1); 75718253fdeSAvi Kivity 75818253fdeSAvi Kivity exec_in_big_real_mode(&insn_popa); 7596055ea1fSAvi Kivity report("pusha/popa 1", 0, 1); 7607d36db35SAvi Kivity } 7617d36db35SAvi Kivity 7622e3f9f1fSThomas Huth static void test_iret(void) 7637d36db35SAvi Kivity { 7647d36db35SAvi Kivity MK_INSN(iret32, "pushf\n\t" 7657d36db35SAvi Kivity "pushl %cs\n\t" 7667d36db35SAvi Kivity "call 1f\n\t" /* a near call will push eip onto the stack */ 7677d36db35SAvi Kivity "jmp 2f\n\t" 768231b4c3bSRoman Bolshakov "1: iretl\n\t" 7697d36db35SAvi Kivity "2:\n\t" 7707d36db35SAvi Kivity ); 7717d36db35SAvi Kivity 7727d36db35SAvi Kivity MK_INSN(iret16, "pushfw\n\t" 7737d36db35SAvi Kivity "pushw %cs\n\t" 7747d36db35SAvi Kivity "callw 1f\n\t" 7757d36db35SAvi Kivity "jmp 2f\n\t" 7767d36db35SAvi Kivity "1: iretw\n\t" 7777d36db35SAvi Kivity "2:\n\t"); 7787d36db35SAvi Kivity 7797d36db35SAvi Kivity MK_INSN(iret_flags32, "pushfl\n\t" 7807d36db35SAvi Kivity "popl %eax\n\t" 7817d36db35SAvi Kivity "andl $~0x2, %eax\n\t" 782964942e8SNadav Amit "orl $0xffc18028, %eax\n\t" 7837d36db35SAvi Kivity "pushl %eax\n\t" 7847d36db35SAvi Kivity "pushl %cs\n\t" 7857d36db35SAvi Kivity "call 1f\n\t" 7867d36db35SAvi Kivity "jmp 2f\n\t" 787231b4c3bSRoman Bolshakov "1: iretl\n\t" 7887d36db35SAvi Kivity "2:\n\t"); 7897d36db35SAvi Kivity 7907d36db35SAvi Kivity MK_INSN(iret_flags16, "pushfw\n\t" 7917d36db35SAvi Kivity "popw %ax\n\t" 7927d36db35SAvi Kivity "and $~0x2, %ax\n\t" 7937d36db35SAvi Kivity "or $0x8028, %ax\n\t" 7947d36db35SAvi Kivity "pushw %ax\n\t" 7957d36db35SAvi Kivity "pushw %cs\n\t" 7967d36db35SAvi Kivity "callw 1f\n\t" 7977d36db35SAvi Kivity "jmp 2f\n\t" 7987d36db35SAvi Kivity "1: iretw\n\t" 7997d36db35SAvi Kivity "2:\n\t"); 8007d36db35SAvi Kivity 801bd62e289SBill Wendling init_inregs(NULL); 8027d36db35SAvi Kivity 80318253fdeSAvi Kivity exec_in_big_real_mode(&insn_iret32); 8046055ea1fSAvi Kivity report("iret 1", 0, 1); 8057d36db35SAvi Kivity 80618253fdeSAvi Kivity exec_in_big_real_mode(&insn_iret16); 8076055ea1fSAvi Kivity report("iret 2", 0, 1); 8087d36db35SAvi Kivity 80918253fdeSAvi Kivity exec_in_big_real_mode(&insn_iret_flags32); 8106055ea1fSAvi Kivity report("iret 3", R_AX, 1); 811964942e8SNadav Amit report("rflags.rf", ~0, !(outregs.eflags & (1 << 16))); 81218253fdeSAvi Kivity 81318253fdeSAvi Kivity exec_in_big_real_mode(&insn_iret_flags16); 8146055ea1fSAvi Kivity report("iret 4", R_AX, 1); 8157d36db35SAvi Kivity } 8167d36db35SAvi Kivity 8172e3f9f1fSThomas Huth static void test_int(void) 81896b9ca1eSMohammed Gamal { 819bd62e289SBill Wendling init_inregs(NULL); 82096b9ca1eSMohammed Gamal 82196b9ca1eSMohammed Gamal *(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */ 82296b9ca1eSMohammed Gamal *(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */ 82396b9ca1eSMohammed Gamal 82496b9ca1eSMohammed Gamal MK_INSN(int11, "int $0x11\n\t"); 82596b9ca1eSMohammed Gamal 82618253fdeSAvi Kivity exec_in_big_real_mode(&insn_int11); 8276055ea1fSAvi Kivity report("int 1", 0, 1); 82896b9ca1eSMohammed Gamal } 82996b9ca1eSMohammed Gamal 8308202cf84SRoman Bolshakov static void test_sti_inhibit(void) 8318202cf84SRoman Bolshakov { 8328202cf84SRoman Bolshakov init_inregs(NULL); 8338202cf84SRoman Bolshakov 8348202cf84SRoman Bolshakov *(u32 *)(0x73 * 4) = 0x1000; /* Store IRQ 11 handler in the IDT */ 8358202cf84SRoman Bolshakov *(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */ 8368202cf84SRoman Bolshakov 8378202cf84SRoman Bolshakov MK_INSN(sti_inhibit, "cli\n\t" 8388202cf84SRoman Bolshakov "movw $0x200b, %dx\n\t" 8398202cf84SRoman Bolshakov "movl $1, %eax\n\t" 8408202cf84SRoman Bolshakov "outl %eax, %dx\n\t" /* Set IRQ11 */ 8418202cf84SRoman Bolshakov "movl $0, %eax\n\t" 8428202cf84SRoman Bolshakov "outl %eax, %dx\n\t" /* Clear IRQ11 */ 8438202cf84SRoman Bolshakov "sti\n\t" 8448202cf84SRoman Bolshakov "hlt\n\t"); 8458202cf84SRoman Bolshakov exec_in_big_real_mode(&insn_sti_inhibit); 8468202cf84SRoman Bolshakov 8478202cf84SRoman Bolshakov report("sti inhibit", ~0, 1); 8488202cf84SRoman Bolshakov } 8498202cf84SRoman Bolshakov 8502e3f9f1fSThomas Huth static void test_imul(void) 851fa74f8a6SMohammed Gamal { 852fa74f8a6SMohammed Gamal MK_INSN(imul8_1, "mov $2, %al\n\t" 853fa74f8a6SMohammed Gamal "mov $-4, %cx\n\t" 854fa74f8a6SMohammed Gamal "imul %cl\n\t"); 855fa74f8a6SMohammed Gamal 856fa74f8a6SMohammed Gamal MK_INSN(imul16_1, "mov $2, %ax\n\t" 857fa74f8a6SMohammed Gamal "mov $-4, %cx\n\t" 858fa74f8a6SMohammed Gamal "imul %cx\n\t"); 859fa74f8a6SMohammed Gamal 860fa74f8a6SMohammed Gamal MK_INSN(imul32_1, "mov $2, %eax\n\t" 861fa74f8a6SMohammed Gamal "mov $-4, %ecx\n\t" 862fa74f8a6SMohammed Gamal "imul %ecx\n\t"); 863fa74f8a6SMohammed Gamal 864fa74f8a6SMohammed Gamal MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t" 865fa74f8a6SMohammed Gamal "mov $4, %cx\n\t" 866fa74f8a6SMohammed Gamal "imul %cl\n\t"); 867fa74f8a6SMohammed Gamal 868fa74f8a6SMohammed Gamal MK_INSN(imul16_2, "mov $2, %ax\n\t" 869fa74f8a6SMohammed Gamal "mov $4, %cx\n\t" 870fa74f8a6SMohammed Gamal "imul %cx\n\t"); 871fa74f8a6SMohammed Gamal 872fa74f8a6SMohammed Gamal MK_INSN(imul32_2, "mov $2, %eax\n\t" 873fa74f8a6SMohammed Gamal "mov $4, %ecx\n\t" 874fa74f8a6SMohammed Gamal "imul %ecx\n\t"); 875fa74f8a6SMohammed Gamal 876bd62e289SBill Wendling init_inregs(NULL); 87718253fdeSAvi Kivity 87818253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul8_1); 8796055ea1fSAvi Kivity report("imul 1", R_AX | R_CX | R_DX, (outregs.eax & 0xff) == (u8)-8); 880fa74f8a6SMohammed Gamal 88118253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul16_1); 8826055ea1fSAvi Kivity report("imul 2", R_AX | R_CX | R_DX, outregs.eax == (u16)-8); 883fa74f8a6SMohammed Gamal 88418253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul32_1); 8856055ea1fSAvi Kivity report("imul 3", R_AX | R_CX | R_DX, outregs.eax == (u32)-8); 886fa74f8a6SMohammed Gamal 88718253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul8_2); 8886055ea1fSAvi Kivity report("imul 4", R_AX | R_CX | R_DX, 8896055ea1fSAvi Kivity (outregs.eax & 0xffff) == 8 89081050840SAvi Kivity && (outregs.eax & 0xffff0000) == 0x12340000); 891fa74f8a6SMohammed Gamal 89218253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul16_2); 8936055ea1fSAvi Kivity report("imul 5", R_AX | R_CX | R_DX, outregs.eax == 8); 894fa74f8a6SMohammed Gamal 89518253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul32_2); 8966055ea1fSAvi Kivity report("imul 6", R_AX | R_CX | R_DX, outregs.eax == 8); 897fa74f8a6SMohammed Gamal } 898fa74f8a6SMohammed Gamal 8992e3f9f1fSThomas Huth static void test_mul(void) 90059317bd1SMohammed Gamal { 90159317bd1SMohammed Gamal MK_INSN(mul8, "mov $2, %al\n\t" 90259317bd1SMohammed Gamal "mov $4, %cx\n\t" 90359317bd1SMohammed Gamal "imul %cl\n\t"); 90459317bd1SMohammed Gamal 90559317bd1SMohammed Gamal MK_INSN(mul16, "mov $2, %ax\n\t" 90659317bd1SMohammed Gamal "mov $4, %cx\n\t" 90759317bd1SMohammed Gamal "imul %cx\n\t"); 90859317bd1SMohammed Gamal 90959317bd1SMohammed Gamal MK_INSN(mul32, "mov $2, %eax\n\t" 91059317bd1SMohammed Gamal "mov $4, %ecx\n\t" 91159317bd1SMohammed Gamal "imul %ecx\n\t"); 91259317bd1SMohammed Gamal 913bd62e289SBill Wendling init_inregs(NULL); 91418253fdeSAvi Kivity 91518253fdeSAvi Kivity exec_in_big_real_mode(&insn_mul8); 9166055ea1fSAvi Kivity report("mul 1", R_AX | R_CX | R_DX, (outregs.eax & 0xff) == 8); 91759317bd1SMohammed Gamal 91818253fdeSAvi Kivity exec_in_big_real_mode(&insn_mul16); 9196055ea1fSAvi Kivity report("mul 2", R_AX | R_CX | R_DX, outregs.eax == 8); 92059317bd1SMohammed Gamal 92118253fdeSAvi Kivity exec_in_big_real_mode(&insn_mul32); 9226055ea1fSAvi Kivity report("mul 3", R_AX | R_CX | R_DX, outregs.eax == 8); 92359317bd1SMohammed Gamal } 92459317bd1SMohammed Gamal 9252e3f9f1fSThomas Huth static void test_div(void) 9260d4c7614SMohammed Gamal { 9270d4c7614SMohammed Gamal MK_INSN(div8, "mov $257, %ax\n\t" 9280d4c7614SMohammed Gamal "mov $2, %cl\n\t" 9290d4c7614SMohammed Gamal "div %cl\n\t"); 9300d4c7614SMohammed Gamal 9310d4c7614SMohammed Gamal MK_INSN(div16, "mov $512, %ax\n\t" 9320d4c7614SMohammed Gamal "mov $5, %cx\n\t" 9330d4c7614SMohammed Gamal "div %cx\n\t"); 9340d4c7614SMohammed Gamal 9350d4c7614SMohammed Gamal MK_INSN(div32, "mov $512, %eax\n\t" 9360d4c7614SMohammed Gamal "mov $5, %ecx\n\t" 9370d4c7614SMohammed Gamal "div %ecx\n\t"); 9380d4c7614SMohammed Gamal 939bd62e289SBill Wendling init_inregs(NULL); 94018253fdeSAvi Kivity 94118253fdeSAvi Kivity exec_in_big_real_mode(&insn_div8); 9426055ea1fSAvi Kivity report("div 1", R_AX | R_CX | R_DX, outregs.eax == 384); 9430d4c7614SMohammed Gamal 94418253fdeSAvi Kivity exec_in_big_real_mode(&insn_div16); 9456055ea1fSAvi Kivity report("div 2", R_AX | R_CX | R_DX, 9466055ea1fSAvi Kivity outregs.eax == 102 && outregs.edx == 2); 9470d4c7614SMohammed Gamal 94818253fdeSAvi Kivity exec_in_big_real_mode(&insn_div32); 9496055ea1fSAvi Kivity report("div 3", R_AX | R_CX | R_DX, 9506055ea1fSAvi Kivity outregs.eax == 102 && outregs.edx == 2); 9510d4c7614SMohammed Gamal } 9520d4c7614SMohammed Gamal 9532e3f9f1fSThomas Huth static void test_idiv(void) 9540d4c7614SMohammed Gamal { 9550d4c7614SMohammed Gamal MK_INSN(idiv8, "mov $256, %ax\n\t" 9560d4c7614SMohammed Gamal "mov $-2, %cl\n\t" 9570d4c7614SMohammed Gamal "idiv %cl\n\t"); 9580d4c7614SMohammed Gamal 9590d4c7614SMohammed Gamal MK_INSN(idiv16, "mov $512, %ax\n\t" 9600d4c7614SMohammed Gamal "mov $-2, %cx\n\t" 9610d4c7614SMohammed Gamal "idiv %cx\n\t"); 9620d4c7614SMohammed Gamal 9630d4c7614SMohammed Gamal MK_INSN(idiv32, "mov $512, %eax\n\t" 9640d4c7614SMohammed Gamal "mov $-2, %ecx\n\t" 9650d4c7614SMohammed Gamal "idiv %ecx\n\t"); 9660d4c7614SMohammed Gamal 967bd62e289SBill Wendling init_inregs(NULL); 96818253fdeSAvi Kivity 96918253fdeSAvi Kivity exec_in_big_real_mode(&insn_idiv8); 9706055ea1fSAvi Kivity report("idiv 1", R_AX | R_CX | R_DX, outregs.eax == (u8)-128); 9710d4c7614SMohammed Gamal 97218253fdeSAvi Kivity exec_in_big_real_mode(&insn_idiv16); 9736055ea1fSAvi Kivity report("idiv 2", R_AX | R_CX | R_DX, outregs.eax == (u16)-256); 9740d4c7614SMohammed Gamal 97518253fdeSAvi Kivity exec_in_big_real_mode(&insn_idiv32); 9766055ea1fSAvi Kivity report("idiv 3", R_AX | R_CX | R_DX, outregs.eax == (u32)-256); 9770d4c7614SMohammed Gamal } 9780d4c7614SMohammed Gamal 9792e3f9f1fSThomas Huth static void test_cbw(void) 9806e293cf5SWei Yongjun { 9816e293cf5SWei Yongjun MK_INSN(cbw, "mov $0xFE, %eax \n\t" 9826e293cf5SWei Yongjun "cbw\n\t"); 9836e293cf5SWei Yongjun MK_INSN(cwde, "mov $0xFFFE, %eax \n\t" 9846e293cf5SWei Yongjun "cwde\n\t"); 9856e293cf5SWei Yongjun 986bd62e289SBill Wendling init_inregs(NULL); 98718253fdeSAvi Kivity 98818253fdeSAvi Kivity exec_in_big_real_mode(&insn_cbw); 9896055ea1fSAvi Kivity report("cbq 1", ~0, outregs.eax == 0xFFFE); 9906e293cf5SWei Yongjun 99118253fdeSAvi Kivity exec_in_big_real_mode(&insn_cwde); 9926055ea1fSAvi Kivity report("cwde 1", ~0, outregs.eax == 0xFFFFFFFE); 9936e293cf5SWei Yongjun } 9946e293cf5SWei Yongjun 9952e3f9f1fSThomas Huth static void test_loopcc(void) 996eacef4e2SWei Yongjun { 997eacef4e2SWei Yongjun MK_INSN(loop, "mov $10, %ecx\n\t" 998eacef4e2SWei Yongjun "1: inc %eax\n\t" 999eacef4e2SWei Yongjun "loop 1b\n\t"); 1000eacef4e2SWei Yongjun 1001eacef4e2SWei Yongjun MK_INSN(loope, "mov $10, %ecx\n\t" 1002eacef4e2SWei Yongjun "mov $1, %eax\n\t" 1003eacef4e2SWei Yongjun "1: dec %eax\n\t" 1004eacef4e2SWei Yongjun "loope 1b\n\t"); 1005eacef4e2SWei Yongjun 1006eacef4e2SWei Yongjun MK_INSN(loopne, "mov $10, %ecx\n\t" 1007eacef4e2SWei Yongjun "mov $5, %eax\n\t" 1008eacef4e2SWei Yongjun "1: dec %eax\n\t" 1009eacef4e2SWei Yongjun "loopne 1b\n\t"); 1010eacef4e2SWei Yongjun 1011bd62e289SBill Wendling init_inregs(NULL); 1012eacef4e2SWei Yongjun 101318253fdeSAvi Kivity exec_in_big_real_mode(&insn_loop); 10146055ea1fSAvi Kivity report("LOOPcc short 1", R_AX, outregs.eax == 10); 101518253fdeSAvi Kivity 101618253fdeSAvi Kivity exec_in_big_real_mode(&insn_loope); 10176055ea1fSAvi Kivity report("LOOPcc short 2", R_AX | R_CX, 10186055ea1fSAvi Kivity outregs.eax == -1 && outregs.ecx == 8); 1019eacef4e2SWei Yongjun 102018253fdeSAvi Kivity exec_in_big_real_mode(&insn_loopne); 10216055ea1fSAvi Kivity report("LOOPcc short 3", R_AX | R_CX, 10226055ea1fSAvi Kivity outregs.eax == 0 && outregs.ecx == 5); 1023eacef4e2SWei Yongjun } 1024eacef4e2SWei Yongjun 1025b274feedSAvi Kivity static void test_das(void) 1026b274feedSAvi Kivity { 1027b274feedSAvi Kivity short i; 102881050840SAvi Kivity u16 nr_fail = 0; 1029b274feedSAvi Kivity static unsigned test_cases[1024] = { 1030b274feedSAvi Kivity 0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00, 1031b274feedSAvi Kivity 0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01, 1032b274feedSAvi Kivity 0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02, 1033b274feedSAvi Kivity 0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03, 1034b274feedSAvi Kivity 0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04, 1035b274feedSAvi Kivity 0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05, 1036b274feedSAvi Kivity 0x06000606, 0x8701a606, 0x56100006, 0x9711a006, 1037b274feedSAvi Kivity 0x02000707, 0x8301a707, 0x12100107, 0x9311a107, 1038b274feedSAvi Kivity 0x02000808, 0x8301a808, 0x12100208, 0x9311a208, 1039b274feedSAvi Kivity 0x06000909, 0x8701a909, 0x16100309, 0x9711a309, 1040b274feedSAvi Kivity 0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a, 1041b274feedSAvi Kivity 0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b, 1042b274feedSAvi Kivity 0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c, 1043b274feedSAvi Kivity 0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d, 1044b274feedSAvi Kivity 0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e, 1045b274feedSAvi Kivity 0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f, 1046b274feedSAvi Kivity 0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10, 1047b274feedSAvi Kivity 0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11, 1048b274feedSAvi Kivity 0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12, 1049b274feedSAvi Kivity 0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13, 1050b274feedSAvi Kivity 0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14, 1051b274feedSAvi Kivity 0x02001515, 0x8301b515, 0x16100f15, 0x9711af15, 1052b274feedSAvi Kivity 0x02001616, 0x8301b616, 0x12101016, 0x9311b016, 1053b274feedSAvi Kivity 0x06001717, 0x8701b717, 0x16101117, 0x9711b117, 1054b274feedSAvi Kivity 0x06001818, 0x8701b818, 0x16101218, 0x9711b218, 1055b274feedSAvi Kivity 0x02001919, 0x8301b919, 0x12101319, 0x9311b319, 1056b274feedSAvi Kivity 0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a, 1057b274feedSAvi Kivity 0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b, 1058b274feedSAvi Kivity 0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c, 1059b274feedSAvi Kivity 0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d, 1060b274feedSAvi Kivity 0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e, 1061b274feedSAvi Kivity 0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f, 1062b274feedSAvi Kivity 0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20, 1063b274feedSAvi Kivity 0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21, 1064b274feedSAvi Kivity 0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22, 1065b274feedSAvi Kivity 0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23, 1066b274feedSAvi Kivity 0x06002424, 0x8301c424, 0x16101e24, 0x9711be24, 1067b274feedSAvi Kivity 0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25, 1068b274feedSAvi Kivity 0x02002626, 0x8701c626, 0x12102026, 0x9711c026, 1069b274feedSAvi Kivity 0x06002727, 0x8301c727, 0x16102127, 0x9311c127, 1070b274feedSAvi Kivity 0x06002828, 0x8301c828, 0x16102228, 0x9311c228, 1071b274feedSAvi Kivity 0x02002929, 0x8701c929, 0x12102329, 0x9711c329, 1072b274feedSAvi Kivity 0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a, 1073b274feedSAvi Kivity 0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b, 1074b274feedSAvi Kivity 0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c, 1075b274feedSAvi Kivity 0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d, 1076b274feedSAvi Kivity 0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e, 1077b274feedSAvi Kivity 0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f, 1078b274feedSAvi Kivity 0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30, 1079b274feedSAvi Kivity 0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31, 1080b274feedSAvi Kivity 0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32, 1081b274feedSAvi Kivity 0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33, 1082b274feedSAvi Kivity 0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34, 1083b274feedSAvi Kivity 0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35, 1084b274feedSAvi Kivity 0x06003636, 0x8301d636, 0x16103036, 0x9311d036, 1085b274feedSAvi Kivity 0x02003737, 0x8701d737, 0x12103137, 0x9711d137, 1086b274feedSAvi Kivity 0x02003838, 0x8701d838, 0x12103238, 0x9711d238, 1087b274feedSAvi Kivity 0x06003939, 0x8301d939, 0x16103339, 0x9311d339, 1088b274feedSAvi Kivity 0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a, 1089b274feedSAvi Kivity 0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b, 1090b274feedSAvi Kivity 0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c, 1091b274feedSAvi Kivity 0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d, 1092b274feedSAvi Kivity 0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e, 1093b274feedSAvi Kivity 0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f, 1094b274feedSAvi Kivity 0x02004040, 0x8301e040, 0x16103a40, 0x9311da40, 1095b274feedSAvi Kivity 0x06004141, 0x8701e141, 0x12103b41, 0x9711db41, 1096b274feedSAvi Kivity 0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42, 1097b274feedSAvi Kivity 0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43, 1098b274feedSAvi Kivity 0x06004444, 0x8701e444, 0x12103e44, 0x9711de44, 1099b274feedSAvi Kivity 0x02004545, 0x8301e545, 0x16103f45, 0x9311df45, 1100b274feedSAvi Kivity 0x02004646, 0x8301e646, 0x12104046, 0x9311e046, 1101b274feedSAvi Kivity 0x06004747, 0x8701e747, 0x16104147, 0x9711e147, 1102b274feedSAvi Kivity 0x06004848, 0x8701e848, 0x16104248, 0x9711e248, 1103b274feedSAvi Kivity 0x02004949, 0x8301e949, 0x12104349, 0x9311e349, 1104b274feedSAvi Kivity 0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a, 1105b274feedSAvi Kivity 0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b, 1106b274feedSAvi Kivity 0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c, 1107b274feedSAvi Kivity 0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d, 1108b274feedSAvi Kivity 0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e, 1109b274feedSAvi Kivity 0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f, 1110b274feedSAvi Kivity 0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50, 1111b274feedSAvi Kivity 0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51, 1112b274feedSAvi Kivity 0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52, 1113b274feedSAvi Kivity 0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53, 1114b274feedSAvi Kivity 0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54, 1115b274feedSAvi Kivity 0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55, 1116b274feedSAvi Kivity 0x06005656, 0x8701f656, 0x16105056, 0x9711f056, 1117b274feedSAvi Kivity 0x02005757, 0x8301f757, 0x12105157, 0x9311f157, 1118b274feedSAvi Kivity 0x02005858, 0x8301f858, 0x12105258, 0x9311f258, 1119b274feedSAvi Kivity 0x06005959, 0x8701f959, 0x16105359, 0x9711f359, 1120b274feedSAvi Kivity 0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a, 1121b274feedSAvi Kivity 0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b, 1122b274feedSAvi Kivity 0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c, 1123b274feedSAvi Kivity 0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d, 1124b274feedSAvi Kivity 0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e, 1125b274feedSAvi Kivity 0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f, 1126b274feedSAvi Kivity 0x06006060, 0x47010060, 0x16105a60, 0x9711fa60, 1127b274feedSAvi Kivity 0x02006161, 0x03010161, 0x12105b61, 0x9311fb61, 1128b274feedSAvi Kivity 0x02006262, 0x03010262, 0x16105c62, 0x9711fc62, 1129b274feedSAvi Kivity 0x06006363, 0x07010363, 0x12105d63, 0x9311fd63, 1130b274feedSAvi Kivity 0x02006464, 0x03010464, 0x12105e64, 0x9311fe64, 1131b274feedSAvi Kivity 0x06006565, 0x07010565, 0x16105f65, 0x9711ff65, 1132b274feedSAvi Kivity 0x06006666, 0x07010666, 0x16106066, 0x57110066, 1133b274feedSAvi Kivity 0x02006767, 0x03010767, 0x12106167, 0x13110167, 1134b274feedSAvi Kivity 0x02006868, 0x03010868, 0x12106268, 0x13110268, 1135b274feedSAvi Kivity 0x06006969, 0x07010969, 0x16106369, 0x17110369, 1136b274feedSAvi Kivity 0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a, 1137b274feedSAvi Kivity 0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b, 1138b274feedSAvi Kivity 0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c, 1139b274feedSAvi Kivity 0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d, 1140b274feedSAvi Kivity 0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e, 1141b274feedSAvi Kivity 0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f, 1142b274feedSAvi Kivity 0x02007070, 0x03011070, 0x16106a70, 0x17110a70, 1143b274feedSAvi Kivity 0x06007171, 0x07011171, 0x12106b71, 0x13110b71, 1144b274feedSAvi Kivity 0x06007272, 0x07011272, 0x16106c72, 0x17110c72, 1145b274feedSAvi Kivity 0x02007373, 0x03011373, 0x12106d73, 0x13110d73, 1146b274feedSAvi Kivity 0x06007474, 0x07011474, 0x12106e74, 0x13110e74, 1147b274feedSAvi Kivity 0x02007575, 0x03011575, 0x16106f75, 0x17110f75, 1148b274feedSAvi Kivity 0x02007676, 0x03011676, 0x12107076, 0x13111076, 1149b274feedSAvi Kivity 0x06007777, 0x07011777, 0x16107177, 0x17111177, 1150b274feedSAvi Kivity 0x06007878, 0x07011878, 0x16107278, 0x17111278, 1151b274feedSAvi Kivity 0x02007979, 0x03011979, 0x12107379, 0x13111379, 1152b274feedSAvi Kivity 0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a, 1153b274feedSAvi Kivity 0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b, 1154b274feedSAvi Kivity 0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c, 1155b274feedSAvi Kivity 0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d, 1156b274feedSAvi Kivity 0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e, 1157b274feedSAvi Kivity 0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f, 1158b274feedSAvi Kivity 0x82008080, 0x03012080, 0x12107a80, 0x13111a80, 1159b274feedSAvi Kivity 0x86008181, 0x07012181, 0x16107b81, 0x17111b81, 1160b274feedSAvi Kivity 0x86008282, 0x07012282, 0x12107c82, 0x13111c82, 1161b274feedSAvi Kivity 0x82008383, 0x03012383, 0x16107d83, 0x17111d83, 1162b274feedSAvi Kivity 0x86008484, 0x07012484, 0x16107e84, 0x17111e84, 1163b274feedSAvi Kivity 0x82008585, 0x03012585, 0x12107f85, 0x13111f85, 1164b274feedSAvi Kivity 0x82008686, 0x03012686, 0x92108086, 0x13112086, 1165b274feedSAvi Kivity 0x86008787, 0x07012787, 0x96108187, 0x17112187, 1166b274feedSAvi Kivity 0x86008888, 0x07012888, 0x96108288, 0x17112288, 1167b274feedSAvi Kivity 0x82008989, 0x03012989, 0x92108389, 0x13112389, 1168b274feedSAvi Kivity 0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a, 1169b274feedSAvi Kivity 0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b, 1170b274feedSAvi Kivity 0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c, 1171b274feedSAvi Kivity 0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d, 1172b274feedSAvi Kivity 0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e, 1173b274feedSAvi Kivity 0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f, 1174b274feedSAvi Kivity 0x86009090, 0x07013090, 0x92108a90, 0x13112a90, 1175b274feedSAvi Kivity 0x82009191, 0x03013191, 0x96108b91, 0x17112b91, 1176b274feedSAvi Kivity 0x82009292, 0x03013292, 0x92108c92, 0x13112c92, 1177b274feedSAvi Kivity 0x86009393, 0x07013393, 0x96108d93, 0x17112d93, 1178b274feedSAvi Kivity 0x82009494, 0x03013494, 0x96108e94, 0x17112e94, 1179b274feedSAvi Kivity 0x86009595, 0x07013595, 0x92108f95, 0x13112f95, 1180b274feedSAvi Kivity 0x86009696, 0x07013696, 0x96109096, 0x17113096, 1181b274feedSAvi Kivity 0x82009797, 0x03013797, 0x92109197, 0x13113197, 1182b274feedSAvi Kivity 0x82009898, 0x03013898, 0x92109298, 0x13113298, 1183b274feedSAvi Kivity 0x86009999, 0x07013999, 0x96109399, 0x17113399, 1184b274feedSAvi Kivity 0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a, 1185b274feedSAvi Kivity 0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b, 1186b274feedSAvi Kivity 0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c, 1187b274feedSAvi Kivity 0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d, 1188b274feedSAvi Kivity 0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e, 1189b274feedSAvi Kivity 0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f, 1190b274feedSAvi Kivity 0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0, 1191b274feedSAvi Kivity 0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1, 1192b274feedSAvi Kivity 0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2, 1193b274feedSAvi Kivity 0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3, 1194b274feedSAvi Kivity 0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4, 1195b274feedSAvi Kivity 0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5, 1196b274feedSAvi Kivity 0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6, 1197b274feedSAvi Kivity 0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7, 1198b274feedSAvi Kivity 0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8, 1199b274feedSAvi Kivity 0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9, 1200b274feedSAvi Kivity 0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa, 1201b274feedSAvi Kivity 0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab, 1202b274feedSAvi Kivity 0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac, 1203b274feedSAvi Kivity 0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad, 1204b274feedSAvi Kivity 0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae, 1205b274feedSAvi Kivity 0x130049af, 0x130149af, 0x131049af, 0x131149af, 1206b274feedSAvi Kivity 0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0, 1207b274feedSAvi Kivity 0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1, 1208b274feedSAvi Kivity 0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2, 1209b274feedSAvi Kivity 0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3, 1210b274feedSAvi Kivity 0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4, 1211b274feedSAvi Kivity 0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5, 1212b274feedSAvi Kivity 0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6, 1213b274feedSAvi Kivity 0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7, 1214b274feedSAvi Kivity 0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8, 1215b274feedSAvi Kivity 0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9, 1216b274feedSAvi Kivity 0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba, 1217b274feedSAvi Kivity 0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb, 1218b274feedSAvi Kivity 0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc, 1219b274feedSAvi Kivity 0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd, 1220b274feedSAvi Kivity 0x130058be, 0x130158be, 0x131058be, 0x131158be, 1221b274feedSAvi Kivity 0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf, 1222b274feedSAvi Kivity 0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0, 1223b274feedSAvi Kivity 0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1, 1224b274feedSAvi Kivity 0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2, 1225b274feedSAvi Kivity 0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3, 1226b274feedSAvi Kivity 0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4, 1227b274feedSAvi Kivity 0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5, 1228b274feedSAvi Kivity 0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6, 1229b274feedSAvi Kivity 0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7, 1230b274feedSAvi Kivity 0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8, 1231b274feedSAvi Kivity 0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9, 1232b274feedSAvi Kivity 0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca, 1233b274feedSAvi Kivity 0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb, 1234b274feedSAvi Kivity 0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc, 1235b274feedSAvi Kivity 0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd, 1236b274feedSAvi Kivity 0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce, 1237b274feedSAvi Kivity 0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf, 1238b274feedSAvi Kivity 0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0, 1239b274feedSAvi Kivity 0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1, 1240b274feedSAvi Kivity 0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2, 1241b274feedSAvi Kivity 0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3, 1242b274feedSAvi Kivity 0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4, 1243b274feedSAvi Kivity 0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5, 1244b274feedSAvi Kivity 0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6, 1245b274feedSAvi Kivity 0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7, 1246b274feedSAvi Kivity 0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8, 1247b274feedSAvi Kivity 0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9, 1248b274feedSAvi Kivity 0x170074da, 0x170174da, 0x171074da, 0x171174da, 1249b274feedSAvi Kivity 0x130075db, 0x130175db, 0x131075db, 0x131175db, 1250b274feedSAvi Kivity 0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc, 1251b274feedSAvi Kivity 0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd, 1252b274feedSAvi Kivity 0x170078de, 0x170178de, 0x171078de, 0x171178de, 1253b274feedSAvi Kivity 0x130079df, 0x130179df, 0x131079df, 0x131179df, 1254b274feedSAvi Kivity 0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0, 1255b274feedSAvi Kivity 0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1, 1256b274feedSAvi Kivity 0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2, 1257b274feedSAvi Kivity 0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3, 1258b274feedSAvi Kivity 0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4, 1259b274feedSAvi Kivity 0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5, 1260b274feedSAvi Kivity 0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6, 1261b274feedSAvi Kivity 0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7, 1262b274feedSAvi Kivity 0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8, 1263b274feedSAvi Kivity 0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9, 1264b274feedSAvi Kivity 0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea, 1265b274feedSAvi Kivity 0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb, 1266b274feedSAvi Kivity 0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec, 1267b274feedSAvi Kivity 0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed, 1268b274feedSAvi Kivity 0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee, 1269b274feedSAvi Kivity 0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef, 1270b274feedSAvi Kivity 0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0, 1271b274feedSAvi Kivity 0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1, 1272b274feedSAvi Kivity 0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2, 1273b274feedSAvi Kivity 0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3, 1274b274feedSAvi Kivity 0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4, 1275b274feedSAvi Kivity 0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5, 1276b274feedSAvi Kivity 0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6, 1277b274feedSAvi Kivity 0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7, 1278b274feedSAvi Kivity 0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8, 1279b274feedSAvi Kivity 0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9, 1280b274feedSAvi Kivity 0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa, 1281b274feedSAvi Kivity 0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb, 1282b274feedSAvi Kivity 0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc, 1283b274feedSAvi Kivity 0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd, 1284b274feedSAvi Kivity 0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe, 1285b274feedSAvi Kivity 0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff, 1286b274feedSAvi Kivity }; 1287b274feedSAvi Kivity 1288b274feedSAvi Kivity MK_INSN(das, "das"); 1289b274feedSAvi Kivity 1290bd62e289SBill Wendling init_inregs(NULL); 129118253fdeSAvi Kivity 1292b274feedSAvi Kivity for (i = 0; i < 1024; ++i) { 1293b274feedSAvi Kivity unsigned tmp = test_cases[i]; 1294b274feedSAvi Kivity inregs.eax = tmp & 0xff; 1295b274feedSAvi Kivity inregs.eflags = (tmp >> 16) & 0xff; 129618253fdeSAvi Kivity exec_in_big_real_mode(&insn_das); 129718253fdeSAvi Kivity if (!regs_equal(R_AX) 1298b274feedSAvi Kivity || outregs.eax != ((tmp >> 8) & 0xff) 1299b274feedSAvi Kivity || (outregs.eflags & 0xff) != (tmp >> 24)) { 130081050840SAvi Kivity ++nr_fail; 130181050840SAvi Kivity break; 1302b274feedSAvi Kivity } 1303b274feedSAvi Kivity } 13046055ea1fSAvi Kivity report("DAS", ~0, nr_fail == 0); 1305b274feedSAvi Kivity } 1306b274feedSAvi Kivity 13072e3f9f1fSThomas Huth static void test_cwd_cdq(void) 13080cbd5b06SMohammed Gamal { 13090cbd5b06SMohammed Gamal /* Sign-bit set */ 13100cbd5b06SMohammed Gamal MK_INSN(cwd_1, "mov $0x8000, %ax\n\t" 13110cbd5b06SMohammed Gamal "cwd\n\t"); 13120cbd5b06SMohammed Gamal 13130cbd5b06SMohammed Gamal /* Sign-bit not set */ 13140cbd5b06SMohammed Gamal MK_INSN(cwd_2, "mov $0x1000, %ax\n\t" 13150cbd5b06SMohammed Gamal "cwd\n\t"); 13160cbd5b06SMohammed Gamal 13170cbd5b06SMohammed Gamal /* Sign-bit set */ 13180cbd5b06SMohammed Gamal MK_INSN(cdq_1, "mov $0x80000000, %eax\n\t" 13190cbd5b06SMohammed Gamal "cdq\n\t"); 13200cbd5b06SMohammed Gamal 13210cbd5b06SMohammed Gamal /* Sign-bit not set */ 13220cbd5b06SMohammed Gamal MK_INSN(cdq_2, "mov $0x10000000, %eax\n\t" 13230cbd5b06SMohammed Gamal "cdq\n\t"); 13240cbd5b06SMohammed Gamal 1325bd62e289SBill Wendling init_inregs(NULL); 132618253fdeSAvi Kivity 132718253fdeSAvi Kivity exec_in_big_real_mode(&insn_cwd_1); 13286055ea1fSAvi Kivity report("cwd 1", R_AX | R_DX, 13296055ea1fSAvi Kivity outregs.eax == 0x8000 && outregs.edx == 0xffff); 13300cbd5b06SMohammed Gamal 133118253fdeSAvi Kivity exec_in_big_real_mode(&insn_cwd_2); 13326055ea1fSAvi Kivity report("cwd 2", R_AX | R_DX, 13336055ea1fSAvi Kivity outregs.eax == 0x1000 && outregs.edx == 0); 13340cbd5b06SMohammed Gamal 133518253fdeSAvi Kivity exec_in_big_real_mode(&insn_cdq_1); 13366055ea1fSAvi Kivity report("cdq 1", R_AX | R_DX, 13376055ea1fSAvi Kivity outregs.eax == 0x80000000 && outregs.edx == 0xffffffff); 13380cbd5b06SMohammed Gamal 133918253fdeSAvi Kivity exec_in_big_real_mode(&insn_cdq_2); 13406055ea1fSAvi Kivity report("cdq 2", R_AX | R_DX, 13416055ea1fSAvi Kivity outregs.eax == 0x10000000 && outregs.edx == 0); 13420cbd5b06SMohammed Gamal } 13430cbd5b06SMohammed Gamal 134437f51a4aSWei Yongjun static struct { 134537f51a4aSWei Yongjun void *address; 134637f51a4aSWei Yongjun unsigned short sel; 134737f51a4aSWei Yongjun } __attribute__((packed)) desc = { 134837f51a4aSWei Yongjun (void *)0x1234, 134937f51a4aSWei Yongjun 0x10, 135037f51a4aSWei Yongjun }; 135137f51a4aSWei Yongjun 13522e3f9f1fSThomas Huth static void test_lds_lss(void) 135337f51a4aSWei Yongjun { 1354bd62e289SBill Wendling init_inregs(&(struct regs){ .ebx = (unsigned long)&desc }); 135537f51a4aSWei Yongjun 1356231b4c3bSRoman Bolshakov MK_INSN(lds, "pushl %ds\n\t" 135737f51a4aSWei Yongjun "lds (%ebx), %eax\n\t" 135837f51a4aSWei Yongjun "mov %ds, %ebx\n\t" 1359231b4c3bSRoman Bolshakov "popl %ds\n\t"); 136037f51a4aSWei Yongjun exec_in_big_real_mode(&insn_lds); 136137f51a4aSWei Yongjun report("lds", R_AX | R_BX, 136237f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 136337f51a4aSWei Yongjun outregs.ebx == desc.sel); 136437f51a4aSWei Yongjun 1365eb6687a2SBill Wendling MK_INSN(les, "les (%ebx), %eax\n\t" 1366eb6687a2SBill Wendling "mov %es, %ebx\n\t"); 136737f51a4aSWei Yongjun exec_in_big_real_mode(&insn_les); 136837f51a4aSWei Yongjun report("les", R_AX | R_BX, 136937f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 137037f51a4aSWei Yongjun outregs.ebx == desc.sel); 137137f51a4aSWei Yongjun 1372231b4c3bSRoman Bolshakov MK_INSN(lfs, "pushl %fs\n\t" 137337f51a4aSWei Yongjun "lfs (%ebx), %eax\n\t" 137437f51a4aSWei Yongjun "mov %fs, %ebx\n\t" 1375231b4c3bSRoman Bolshakov "popl %fs\n\t"); 137637f51a4aSWei Yongjun exec_in_big_real_mode(&insn_lfs); 137737f51a4aSWei Yongjun report("lfs", R_AX | R_BX, 137837f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 137937f51a4aSWei Yongjun outregs.ebx == desc.sel); 138037f51a4aSWei Yongjun 1381231b4c3bSRoman Bolshakov MK_INSN(lgs, "pushl %gs\n\t" 138237f51a4aSWei Yongjun "lgs (%ebx), %eax\n\t" 138337f51a4aSWei Yongjun "mov %gs, %ebx\n\t" 1384231b4c3bSRoman Bolshakov "popl %gs\n\t"); 138537f51a4aSWei Yongjun exec_in_big_real_mode(&insn_lgs); 138637f51a4aSWei Yongjun report("lgs", R_AX | R_BX, 138737f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 138837f51a4aSWei Yongjun outregs.ebx == desc.sel); 138937f51a4aSWei Yongjun 1390d7903be6SNadav Amit MK_INSN(lss, "mov %ss, %dx\n\t" 139137f51a4aSWei Yongjun "lss (%ebx), %eax\n\t" 139237f51a4aSWei Yongjun "mov %ss, %ebx\n\t" 1393d7903be6SNadav Amit "mov %dx, %ss\n\t"); 139437f51a4aSWei Yongjun exec_in_big_real_mode(&insn_lss); 139537f51a4aSWei Yongjun report("lss", R_AX | R_BX, 139637f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 139737f51a4aSWei Yongjun outregs.ebx == desc.sel); 139837f51a4aSWei Yongjun } 139937f51a4aSWei Yongjun 14002e3f9f1fSThomas Huth static void test_jcxz(void) 1401b1c7c575SWei Yongjun { 1402b1c7c575SWei Yongjun MK_INSN(jcxz1, "jcxz 1f\n\t" 1403b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1404b1c7c575SWei Yongjun "1:\n\t"); 1405b1c7c575SWei Yongjun MK_INSN(jcxz2, "mov $0x100, %ecx\n\t" 1406b1c7c575SWei Yongjun "jcxz 1f\n\t" 1407b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1408b1c7c575SWei Yongjun "mov $0, %ecx\n\t" 1409b1c7c575SWei Yongjun "1:\n\t"); 1410b1c7c575SWei Yongjun MK_INSN(jcxz3, "mov $0x10000, %ecx\n\t" 1411b1c7c575SWei Yongjun "jcxz 1f\n\t" 1412b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1413b1c7c575SWei Yongjun "1:\n\t"); 1414b1c7c575SWei Yongjun MK_INSN(jecxz1, "jecxz 1f\n\t" 1415b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1416b1c7c575SWei Yongjun "1:\n\t"); 1417b1c7c575SWei Yongjun MK_INSN(jecxz2, "mov $0x10000, %ecx\n\t" 1418b1c7c575SWei Yongjun "jecxz 1f\n\t" 1419b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1420b1c7c575SWei Yongjun "mov $0, %ecx\n\t" 1421b1c7c575SWei Yongjun "1:\n\t"); 1422b1c7c575SWei Yongjun 1423bd62e289SBill Wendling init_inregs(NULL); 1424b1c7c575SWei Yongjun 1425b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jcxz1); 1426b1c7c575SWei Yongjun report("jcxz short 1", 0, 1); 1427b1c7c575SWei Yongjun 1428b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jcxz2); 1429b1c7c575SWei Yongjun report("jcxz short 2", R_AX, outregs.eax == 0x1234); 1430b1c7c575SWei Yongjun 1431b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jcxz3); 1432b1c7c575SWei Yongjun report("jcxz short 3", R_CX, outregs.ecx == 0x10000); 1433b1c7c575SWei Yongjun 1434b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jecxz1); 1435b1c7c575SWei Yongjun report("jecxz short 1", 0, 1); 1436b1c7c575SWei Yongjun 1437b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jecxz2); 1438b1c7c575SWei Yongjun report("jecxz short 2", R_AX, outregs.eax == 0x1234); 1439b1c7c575SWei Yongjun } 1440b1c7c575SWei Yongjun 14418f578e98SAvi Kivity static void test_cpuid(void) 14428f578e98SAvi Kivity { 14438f578e98SAvi Kivity MK_INSN(cpuid, "cpuid"); 14448f578e98SAvi Kivity unsigned function = 0x1234; 14458f578e98SAvi Kivity unsigned eax, ebx, ecx, edx; 14468f578e98SAvi Kivity 1447bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = function }); 1448bd62e289SBill Wendling 1449bd62e289SBill Wendling eax = inregs.eax; 1450bd62e289SBill Wendling ecx = inregs.ecx; 1451674d2dbeSPaolo Bonzini asm("cpuid" : "+a"(eax), "=b"(ebx), "+c"(ecx), "=d"(edx)); 14528f578e98SAvi Kivity exec_in_big_real_mode(&insn_cpuid); 14538f578e98SAvi Kivity report("cpuid", R_AX|R_BX|R_CX|R_DX, 14548f578e98SAvi Kivity outregs.eax == eax && outregs.ebx == ebx 14558f578e98SAvi Kivity && outregs.ecx == ecx && outregs.edx == edx); 14568f578e98SAvi Kivity } 14578f578e98SAvi Kivity 1458ed93f43bSAvi Kivity static void test_ss_base_for_esp_ebp(void) 1459ed93f43bSAvi Kivity { 1460ed93f43bSAvi Kivity MK_INSN(ssrel1, "mov %ss, %ax; mov %bx, %ss; movl (%ebp), %ebx; mov %ax, %ss"); 1461ed93f43bSAvi Kivity MK_INSN(ssrel2, "mov %ss, %ax; mov %bx, %ss; movl (%ebp,%edi,8), %ebx; mov %ax, %ss"); 1462ed93f43bSAvi Kivity static unsigned array[] = { 0x12345678, 0, 0, 0, 0x87654321 }; 1463ed93f43bSAvi Kivity 1464bd62e289SBill Wendling init_inregs(&(struct regs){ .ebx = 1, .ebp = (unsigned)array }); 1465bd62e289SBill Wendling 1466ed93f43bSAvi Kivity exec_in_big_real_mode(&insn_ssrel1); 1467ed93f43bSAvi Kivity report("ss relative addressing (1)", R_AX | R_BX, outregs.ebx == 0x87654321); 1468bd62e289SBill Wendling 1469ed93f43bSAvi Kivity inregs.ebx = 1; 1470ed93f43bSAvi Kivity inregs.ebp = (unsigned)array; 1471ed93f43bSAvi Kivity inregs.edi = 0; 1472ed93f43bSAvi Kivity exec_in_big_real_mode(&insn_ssrel2); 1473ed93f43bSAvi Kivity report("ss relative addressing (2)", R_AX | R_BX, outregs.ebx == 0x87654321); 1474ed93f43bSAvi Kivity } 1475ed93f43bSAvi Kivity 1476975ca087SPeter Feiner extern unsigned long long r_gdt[]; 1477975ca087SPeter Feiner 1478c2281fa4SAvi Kivity static void test_sgdt_sidt(void) 1479c2281fa4SAvi Kivity { 1480c2281fa4SAvi Kivity MK_INSN(sgdt, "sgdtw (%eax)"); 1481c2281fa4SAvi Kivity MK_INSN(sidt, "sidtw (%eax)"); 1482975ca087SPeter Feiner struct table_descr x, y; 1483c2281fa4SAvi Kivity 1484bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = (unsigned)&y }); 1485bd62e289SBill Wendling 1486c2281fa4SAvi Kivity asm volatile("sgdtw %0" : "=m"(x)); 1487c2281fa4SAvi Kivity exec_in_big_real_mode(&insn_sgdt); 1488975ca087SPeter Feiner report("sgdt", 0, x.limit == y.limit && x.base == y.base); 1489c2281fa4SAvi Kivity 1490c2281fa4SAvi Kivity inregs.eax = (unsigned)&y; 1491c2281fa4SAvi Kivity asm volatile("sidtw %0" : "=m"(x)); 1492c2281fa4SAvi Kivity exec_in_big_real_mode(&insn_sidt); 1493975ca087SPeter Feiner report("sidt", 0, x.limit == y.limit && x.base == y.base); 1494c2281fa4SAvi Kivity } 1495c2281fa4SAvi Kivity 149688b6dac4SPaolo Bonzini static void test_sahf(void) 149788b6dac4SPaolo Bonzini { 149888b6dac4SPaolo Bonzini MK_INSN(sahf, "sahf; pushfw; mov (%esp), %al; popfw"); 149988b6dac4SPaolo Bonzini 1500bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0xfd00 }); 1501bd62e289SBill Wendling 150288b6dac4SPaolo Bonzini exec_in_big_real_mode(&insn_sahf); 150388b6dac4SPaolo Bonzini report("sahf", R_AX, outregs.eax == (inregs.eax | 0xd7)); 150488b6dac4SPaolo Bonzini } 150588b6dac4SPaolo Bonzini 15067ae3645aSAvi Kivity static void test_lahf(void) 15077ae3645aSAvi Kivity { 15087ae3645aSAvi Kivity MK_INSN(lahf, "pushfw; mov %al, (%esp); popfw; lahf"); 15097ae3645aSAvi Kivity 1510bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0xc7 }); 1511bd62e289SBill Wendling 15127ae3645aSAvi Kivity exec_in_big_real_mode(&insn_lahf); 15137ae3645aSAvi Kivity report("lahf", R_AX, (outregs.eax >> 8) == inregs.eax); 15147ae3645aSAvi Kivity } 15157ae3645aSAvi Kivity 1516fd9ea640SAvi Kivity static void test_movzx_movsx(void) 1517fd9ea640SAvi Kivity { 1518fd9ea640SAvi Kivity MK_INSN(movsx, "movsx %al, %ebx"); 1519fd9ea640SAvi Kivity MK_INSN(movzx, "movzx %al, %ebx"); 15203013e079SGleb Natapov MK_INSN(movzsah, "movsx %ah, %ebx"); 15213013e079SGleb Natapov MK_INSN(movzxah, "movzx %ah, %ebx"); 1522fd9ea640SAvi Kivity 1523bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x1234569c }); 1524bd62e289SBill Wendling 1525fd9ea640SAvi Kivity exec_in_big_real_mode(&insn_movsx); 1526fd9ea640SAvi Kivity report("movsx", R_BX, outregs.ebx == (signed char)inregs.eax); 1527fd9ea640SAvi Kivity exec_in_big_real_mode(&insn_movzx); 1528fd9ea640SAvi Kivity report("movzx", R_BX, outregs.ebx == (unsigned char)inregs.eax); 15293013e079SGleb Natapov exec_in_big_real_mode(&insn_movzsah); 15303013e079SGleb Natapov report("movsx ah", R_BX, outregs.ebx == (signed char)(inregs.eax>>8)); 15313013e079SGleb Natapov exec_in_big_real_mode(&insn_movzxah); 15323013e079SGleb Natapov report("movzx ah", R_BX, outregs.ebx == (unsigned char)(inregs.eax >> 8)); 1533fd9ea640SAvi Kivity } 1534fd9ea640SAvi Kivity 1535b493b2e8SAvi Kivity static void test_bswap(void) 1536b493b2e8SAvi Kivity { 1537b493b2e8SAvi Kivity MK_INSN(bswap, "bswap %ecx"); 1538b493b2e8SAvi Kivity 1539bd62e289SBill Wendling init_inregs(&(struct regs){ .ecx = 0x12345678 }); 1540bd62e289SBill Wendling 1541b493b2e8SAvi Kivity exec_in_big_real_mode(&insn_bswap); 1542b493b2e8SAvi Kivity report("bswap", R_CX, outregs.ecx == 0x78563412); 1543b493b2e8SAvi Kivity } 1544b493b2e8SAvi Kivity 15458cd86387SGleb Natapov static void test_aad(void) 15468cd86387SGleb Natapov { 15478cd86387SGleb Natapov MK_INSN(aad, "aad"); 15488cd86387SGleb Natapov 1549bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x12345678 }); 1550bd62e289SBill Wendling 15518cd86387SGleb Natapov exec_in_big_real_mode(&insn_aad); 15528cd86387SGleb Natapov report("aad", R_AX, outregs.eax == 0x123400d4); 15538cd86387SGleb Natapov } 15548cd86387SGleb Natapov 15552a9b5718SPaolo Bonzini static void test_aam(void) 15562a9b5718SPaolo Bonzini { 15572a9b5718SPaolo Bonzini MK_INSN(aam, "aam"); 15582a9b5718SPaolo Bonzini 1559bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x76543210 }); 1560bd62e289SBill Wendling 15612a9b5718SPaolo Bonzini exec_in_big_real_mode(&insn_aam); 15622a9b5718SPaolo Bonzini report("aam", R_AX, outregs.eax == 0x76540106); 15632a9b5718SPaolo Bonzini } 15642a9b5718SPaolo Bonzini 15652a9b5718SPaolo Bonzini static void test_xlat(void) 15662a9b5718SPaolo Bonzini { 15672a9b5718SPaolo Bonzini MK_INSN(xlat, "xlat"); 15682a9b5718SPaolo Bonzini u8 table[256]; 15692a9b5718SPaolo Bonzini int i; 15702a9b5718SPaolo Bonzini 15712a9b5718SPaolo Bonzini for (i = 0; i < 256; i++) { 15722a9b5718SPaolo Bonzini table[i] = i + 1; 15732a9b5718SPaolo Bonzini } 15742a9b5718SPaolo Bonzini 1575bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x89abcdef, .ebx = (u32)table }); 1576bd62e289SBill Wendling 15772a9b5718SPaolo Bonzini exec_in_big_real_mode(&insn_xlat); 15782a9b5718SPaolo Bonzini report("xlat", R_AX, outregs.eax == 0x89abcdf0); 15792a9b5718SPaolo Bonzini } 15802a9b5718SPaolo Bonzini 15812a9b5718SPaolo Bonzini static void test_salc(void) 15822a9b5718SPaolo Bonzini { 15832a9b5718SPaolo Bonzini MK_INSN(clc_salc, "clc; .byte 0xd6"); 15842a9b5718SPaolo Bonzini MK_INSN(stc_salc, "stc; .byte 0xd6"); 15852a9b5718SPaolo Bonzini 1586bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x12345678 }); 1587bd62e289SBill Wendling 15882a9b5718SPaolo Bonzini exec_in_big_real_mode(&insn_clc_salc); 15892a9b5718SPaolo Bonzini report("salc (1)", R_AX, outregs.eax == 0x12345600); 15902a9b5718SPaolo Bonzini exec_in_big_real_mode(&insn_stc_salc); 15912a9b5718SPaolo Bonzini report("salc (2)", R_AX, outregs.eax == 0x123456ff); 15922a9b5718SPaolo Bonzini } 15932a9b5718SPaolo Bonzini 15940987db7aSGleb Natapov static void test_fninit(void) 15950987db7aSGleb Natapov { 15960987db7aSGleb Natapov u16 fcw = -1, fsw = -1; 15970987db7aSGleb Natapov MK_INSN(fninit, "fninit ; fnstsw (%eax) ; fnstcw (%ebx)"); 15980987db7aSGleb Natapov 1599bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = (u32)&fsw, .ebx = (u32)&fcw }); 16000987db7aSGleb Natapov 16010987db7aSGleb Natapov exec_in_big_real_mode(&insn_fninit); 16020987db7aSGleb Natapov report("fninit", 0, fsw == 0 && (fcw & 0x103f) == 0x003f); 16030987db7aSGleb Natapov } 16040987db7aSGleb Natapov 16051a4c03a0SArthur Chunqi Li static void test_nopl(void) 16061a4c03a0SArthur Chunqi Li { 16071a4c03a0SArthur Chunqi Li MK_INSN(nopl1, ".byte 0x90\n\r"); // 1 byte nop 16081a4c03a0SArthur Chunqi Li MK_INSN(nopl2, ".byte 0x66, 0x90\n\r"); // 2 bytes nop 16091a4c03a0SArthur Chunqi Li MK_INSN(nopl3, ".byte 0x0f, 0x1f, 0x00\n\r"); // 3 bytes nop 16101a4c03a0SArthur Chunqi Li MK_INSN(nopl4, ".byte 0x0f, 0x1f, 0x40, 0x00\n\r"); // 4 bytes nop 16111a4c03a0SArthur Chunqi Li exec_in_big_real_mode(&insn_nopl1); 16121a4c03a0SArthur Chunqi Li exec_in_big_real_mode(&insn_nopl2); 16131a4c03a0SArthur Chunqi Li exec_in_big_real_mode(&insn_nopl3); 16141a4c03a0SArthur Chunqi Li exec_in_big_real_mode(&insn_nopl4); 16151a4c03a0SArthur Chunqi Li report("nopl", 0, 1); 16161a4c03a0SArthur Chunqi Li } 16171a4c03a0SArthur Chunqi Li 1618b5105e8bSPaolo Bonzini static u32 perf_baseline; 1619b5105e8bSPaolo Bonzini 16207505ea23SPaolo Bonzini #define PERF_COUNT 1000000 1621b5105e8bSPaolo Bonzini 1622b5105e8bSPaolo Bonzini #define MK_INSN_PERF(name, insn) \ 1623b5105e8bSPaolo Bonzini MK_INSN(name, "rdtsc; mov %eax, %ebx; mov %edx, %esi\n" \ 1624b5105e8bSPaolo Bonzini "1:" insn "\n" \ 16257505ea23SPaolo Bonzini ".byte 0x67; loop 1b\n" \ 1626b5105e8bSPaolo Bonzini "rdtsc"); 1627b5105e8bSPaolo Bonzini 1628b5105e8bSPaolo Bonzini static u32 cycles_in_big_real_mode(struct insn_desc *insn) 1629b5105e8bSPaolo Bonzini { 1630b5105e8bSPaolo Bonzini u64 start, end; 1631b5105e8bSPaolo Bonzini 1632bd62e289SBill Wendling init_inregs(&(struct regs){ .ecx = PERF_COUNT }); 1633bd62e289SBill Wendling 1634b5105e8bSPaolo Bonzini exec_in_big_real_mode(insn); 1635b5105e8bSPaolo Bonzini start = ((u64)outregs.esi << 32) | outregs.ebx; 1636b5105e8bSPaolo Bonzini end = ((u64)outregs.edx << 32) | outregs.eax; 1637b5105e8bSPaolo Bonzini 1638b5105e8bSPaolo Bonzini return end - start; 1639b5105e8bSPaolo Bonzini } 1640b5105e8bSPaolo Bonzini 1641b5105e8bSPaolo Bonzini static void test_perf_loop(void) 1642b5105e8bSPaolo Bonzini { 1643b5105e8bSPaolo Bonzini /* 1644b5105e8bSPaolo Bonzini * This test runs simple instructions that should roughly take the 1645b5105e8bSPaolo Bonzini * the same time to emulate: PERF_COUNT iterations of "loop" and 3 1646b5105e8bSPaolo Bonzini * setup instructions. Other performance tests can run PERF_COUNT 1647b5105e8bSPaolo Bonzini * iterations of the same instruction and subtract the cycle count 1648b5105e8bSPaolo Bonzini * of this test. 1649b5105e8bSPaolo Bonzini */ 1650b5105e8bSPaolo Bonzini MK_INSN_PERF(perf_loop, ""); 1651b5105e8bSPaolo Bonzini perf_baseline = cycles_in_big_real_mode(&insn_perf_loop); 1652b5105e8bSPaolo Bonzini print_serial_u32(perf_baseline / (PERF_COUNT + 3)); 1653b5105e8bSPaolo Bonzini print_serial(" cycles/emulated jump instruction\n"); 1654b5105e8bSPaolo Bonzini } 1655b5105e8bSPaolo Bonzini 1656b5105e8bSPaolo Bonzini static void test_perf_mov(void) 1657b5105e8bSPaolo Bonzini { 1658b5105e8bSPaolo Bonzini u32 cyc; 1659b5105e8bSPaolo Bonzini 1660b5105e8bSPaolo Bonzini MK_INSN_PERF(perf_move, "mov %esi, %edi"); 1661b5105e8bSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_move); 1662b5105e8bSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 1663b5105e8bSPaolo Bonzini print_serial(" cycles/emulated move instruction\n"); 1664b5105e8bSPaolo Bonzini } 1665b5105e8bSPaolo Bonzini 1666b5105e8bSPaolo Bonzini static void test_perf_arith(void) 1667b5105e8bSPaolo Bonzini { 1668b5105e8bSPaolo Bonzini u32 cyc; 1669b5105e8bSPaolo Bonzini 1670b5105e8bSPaolo Bonzini MK_INSN_PERF(perf_arith, "add $4, %edi"); 1671b5105e8bSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_arith); 1672b5105e8bSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 1673b5105e8bSPaolo Bonzini print_serial(" cycles/emulated arithmetic instruction\n"); 1674b5105e8bSPaolo Bonzini } 1675b5105e8bSPaolo Bonzini 1676b5105e8bSPaolo Bonzini static void test_perf_memory_load(void) 1677b5105e8bSPaolo Bonzini { 1678b5105e8bSPaolo Bonzini u32 cyc, tmp; 1679b5105e8bSPaolo Bonzini 1680576718d0SBill Wendling MK_INSN_PERF(perf_memory_load, "cmpw $0, (%edi)"); 1681bd62e289SBill Wendling 1682bd62e289SBill Wendling init_inregs(&(struct regs){ .edi = (u32)&tmp }); 1683bd62e289SBill Wendling 1684b5105e8bSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_memory_load); 1685b5105e8bSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 1686b5105e8bSPaolo Bonzini print_serial(" cycles/emulated memory load instruction\n"); 1687b5105e8bSPaolo Bonzini } 1688b5105e8bSPaolo Bonzini 16899306cb8eSPaolo Bonzini static void test_perf_memory_store(void) 16909306cb8eSPaolo Bonzini { 16919306cb8eSPaolo Bonzini u32 cyc, tmp; 16929306cb8eSPaolo Bonzini 1693576718d0SBill Wendling MK_INSN_PERF(perf_memory_store, "movw %ax, (%edi)"); 1694bd62e289SBill Wendling 1695bd62e289SBill Wendling init_inregs(&(struct regs){ .edi = (u32)&tmp }); 1696bd62e289SBill Wendling 16979306cb8eSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_memory_store); 16989306cb8eSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 16999306cb8eSPaolo Bonzini print_serial(" cycles/emulated memory store instruction\n"); 17009306cb8eSPaolo Bonzini } 17019306cb8eSPaolo Bonzini 1702b5105e8bSPaolo Bonzini static void test_perf_memory_rmw(void) 1703b5105e8bSPaolo Bonzini { 1704b5105e8bSPaolo Bonzini u32 cyc, tmp; 1705b5105e8bSPaolo Bonzini 1706576718d0SBill Wendling MK_INSN_PERF(perf_memory_rmw, "addw $1, (%edi)"); 1707bd62e289SBill Wendling 1708bd62e289SBill Wendling init_inregs(&(struct regs){ .edi = (u32)&tmp }); 1709bd62e289SBill Wendling 1710b5105e8bSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_memory_rmw); 1711b5105e8bSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 1712b5105e8bSPaolo Bonzini print_serial(" cycles/emulated memory RMW instruction\n"); 1713b5105e8bSPaolo Bonzini } 1714b5105e8bSPaolo Bonzini 17152e3f9f1fSThomas Huth static void test_dr_mod(void) 17160a5701edSNadav Amit { 17170a5701edSNadav Amit MK_INSN(drmod, "movl %ebx, %dr0\n\t" 17180a5701edSNadav Amit ".byte 0x0f \n\t .byte 0x21 \n\t .byte 0x0\n\t"); 1719bd62e289SBill Wendling 1720bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0xdead, .ebx = 0xaced }); 1721bd62e289SBill Wendling 17220a5701edSNadav Amit exec_in_big_real_mode(&insn_drmod); 17230a5701edSNadav Amit report("mov dr with mod bits", R_AX | R_BX, outregs.eax == 0xaced); 17240a5701edSNadav Amit } 17250a5701edSNadav Amit 17262e3f9f1fSThomas Huth static void test_smsw(void) 172799ee878cSNadav Amit { 172899ee878cSNadav Amit MK_INSN(smsw, "movl %cr0, %ebx\n\t" 172999ee878cSNadav Amit "movl %ebx, %ecx\n\t" 173099ee878cSNadav Amit "or $0x40000000, %ebx\n\t" 173199ee878cSNadav Amit "movl %ebx, %cr0\n\t" 173299ee878cSNadav Amit "smswl %eax\n\t" 173399ee878cSNadav Amit "movl %ecx, %cr0\n\t"); 1734bd62e289SBill Wendling 1735bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x12345678 }); 1736bd62e289SBill Wendling 173799ee878cSNadav Amit exec_in_big_real_mode(&insn_smsw); 173899ee878cSNadav Amit report("smsw", R_AX | R_BX | R_CX, outregs.eax == outregs.ebx); 173999ee878cSNadav Amit } 174099ee878cSNadav Amit 17412e3f9f1fSThomas Huth static void test_xadd(void) 17427bee560dSNadav Amit { 17437bee560dSNadav Amit MK_INSN(xadd, "xaddl %eax, %eax\n\t"); 1744bd62e289SBill Wendling 1745bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x12345678 }); 1746bd62e289SBill Wendling 17477bee560dSNadav Amit exec_in_big_real_mode(&insn_xadd); 17487bee560dSNadav Amit report("xadd", R_AX, outregs.eax == inregs.eax * 2); 17497bee560dSNadav Amit } 17507bee560dSNadav Amit 175199ee878cSNadav Amit 17527d36db35SAvi Kivity void realmode_start(void) 17537d36db35SAvi Kivity { 17547d36db35SAvi Kivity test_null(); 17557d36db35SAvi Kivity 17567d36db35SAvi Kivity test_shld(); 17577d36db35SAvi Kivity test_push_pop(); 17587d36db35SAvi Kivity test_pusha_popa(); 17597d36db35SAvi Kivity test_mov_imm(); 17607d36db35SAvi Kivity test_cmp_imm(); 17617d36db35SAvi Kivity test_add_imm(); 17627d36db35SAvi Kivity test_sub_imm(); 17637d36db35SAvi Kivity test_xor_imm(); 17647d36db35SAvi Kivity test_io(); 17657d36db35SAvi Kivity test_eflags_insn(); 17667d36db35SAvi Kivity test_jcc_short(); 17677d36db35SAvi Kivity test_jcc_near(); 17687d36db35SAvi Kivity /* test_call() uses short jump so call it after testing jcc */ 17697d36db35SAvi Kivity test_call(); 17707d36db35SAvi Kivity /* long jmp test uses call near so test it after testing call */ 17717d36db35SAvi Kivity test_long_jmp(); 17727d36db35SAvi Kivity test_xchg(); 17737d36db35SAvi Kivity test_iret(); 177496b9ca1eSMohammed Gamal test_int(); 17758202cf84SRoman Bolshakov test_sti_inhibit(); 1776fa74f8a6SMohammed Gamal test_imul(); 177759317bd1SMohammed Gamal test_mul(); 17780d4c7614SMohammed Gamal test_div(); 17790d4c7614SMohammed Gamal test_idiv(); 1780eacef4e2SWei Yongjun test_loopcc(); 17816e293cf5SWei Yongjun test_cbw(); 17820cbd5b06SMohammed Gamal test_cwd_cdq(); 1783b274feedSAvi Kivity test_das(); 178437f51a4aSWei Yongjun test_lds_lss(); 1785b1c7c575SWei Yongjun test_jcxz(); 17868f578e98SAvi Kivity test_cpuid(); 1787ed93f43bSAvi Kivity test_ss_base_for_esp_ebp(); 1788c2281fa4SAvi Kivity test_sgdt_sidt(); 17897ae3645aSAvi Kivity test_lahf(); 179088b6dac4SPaolo Bonzini test_sahf(); 1791fd9ea640SAvi Kivity test_movzx_movsx(); 1792b493b2e8SAvi Kivity test_bswap(); 17938cd86387SGleb Natapov test_aad(); 17942a9b5718SPaolo Bonzini test_aam(); 17952a9b5718SPaolo Bonzini test_xlat(); 17962a9b5718SPaolo Bonzini test_salc(); 17970987db7aSGleb Natapov test_fninit(); 17980a5701edSNadav Amit test_dr_mod(); 179999ee878cSNadav Amit test_smsw(); 18001a4c03a0SArthur Chunqi Li test_nopl(); 18017bee560dSNadav Amit test_xadd(); 1802b5105e8bSPaolo Bonzini test_perf_loop(); 1803b5105e8bSPaolo Bonzini test_perf_mov(); 1804b5105e8bSPaolo Bonzini test_perf_arith(); 1805b5105e8bSPaolo Bonzini test_perf_memory_load(); 18069306cb8eSPaolo Bonzini test_perf_memory_store(); 1807b5105e8bSPaolo Bonzini test_perf_memory_rmw(); 18087d36db35SAvi Kivity 1809b393fe28SNadav Amit exit(failed); 18107d36db35SAvi Kivity } 18117d36db35SAvi Kivity 18127d36db35SAvi Kivity unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff }; 18137d36db35SAvi Kivity 1814975ca087SPeter Feiner struct table_descr r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt }; 1815a529af7cSNadav Amit struct table_descr r_idt_descr = { 0x3ff, 0 }; 18167d36db35SAvi Kivity 18177d36db35SAvi Kivity asm( 18187d36db35SAvi Kivity ".section .init \n\t" 18197d36db35SAvi Kivity 18207d36db35SAvi Kivity ".code32 \n\t" 18217d36db35SAvi Kivity 18227d36db35SAvi Kivity "mb_magic = 0x1BADB002 \n\t" 18237d36db35SAvi Kivity "mb_flags = 0x0 \n\t" 18247d36db35SAvi Kivity 18257d36db35SAvi Kivity "# multiboot header \n\t" 18267d36db35SAvi Kivity ".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t" 18277d36db35SAvi Kivity 18287d36db35SAvi Kivity ".globl start \n\t" 18297d36db35SAvi Kivity ".data \n\t" 18307d36db35SAvi Kivity ". = . + 4096 \n\t" 18317d36db35SAvi Kivity "stacktop: \n\t" 18327d36db35SAvi Kivity 18337d36db35SAvi Kivity ".text \n\t" 18347d36db35SAvi Kivity "start: \n\t" 18357d36db35SAvi Kivity "lgdt r_gdt_descr \n\t" 1836a529af7cSNadav Amit "lidt r_idt_descr \n\t" 18377d36db35SAvi Kivity "ljmp $8, $1f; 1: \n\t" 18387d36db35SAvi Kivity ".code16gcc \n\t" 18397d36db35SAvi Kivity "mov $16, %eax \n\t" 18407d36db35SAvi Kivity "mov %ax, %ds \n\t" 18417d36db35SAvi Kivity "mov %ax, %es \n\t" 18427d36db35SAvi Kivity "mov %ax, %fs \n\t" 18437d36db35SAvi Kivity "mov %ax, %gs \n\t" 18447d36db35SAvi Kivity "mov %ax, %ss \n\t" 18457d36db35SAvi Kivity "mov %cr0, %eax \n\t" 18467d36db35SAvi Kivity "btc $0, %eax \n\t" 18477d36db35SAvi Kivity "mov %eax, %cr0 \n\t" 18487d36db35SAvi Kivity "ljmp $0, $realmode_entry \n\t" 18497d36db35SAvi Kivity 18507d36db35SAvi Kivity "realmode_entry: \n\t" 18517d36db35SAvi Kivity 18527d36db35SAvi Kivity "xor %ax, %ax \n\t" 18537d36db35SAvi Kivity "mov %ax, %ds \n\t" 18547d36db35SAvi Kivity "mov %ax, %es \n\t" 18557d36db35SAvi Kivity "mov %ax, %ss \n\t" 18567d36db35SAvi Kivity "mov %ax, %fs \n\t" 18577d36db35SAvi Kivity "mov %ax, %gs \n\t" 18587d36db35SAvi Kivity "mov $stacktop, %esp\n\t" 18597d36db35SAvi Kivity "ljmp $0, $realmode_start \n\t" 18607d36db35SAvi Kivity 18617d36db35SAvi Kivity ".code16gcc \n\t" 18627d36db35SAvi Kivity ); 1863