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); 80f366255fSPaolo Bonzini } 81f366255fSPaolo Bonzini #endif 82f366255fSPaolo Bonzini 837d36db35SAvi Kivity static void print_serial(const char *buf) 847d36db35SAvi Kivity { 857d36db35SAvi Kivity unsigned long len = strlen(buf); 86f366255fSPaolo Bonzini #ifdef USE_SERIAL 87f366255fSPaolo Bonzini unsigned long i; 88f366255fSPaolo Bonzini if (!serial_inited) { 89f366255fSPaolo Bonzini serial_init(); 90f366255fSPaolo Bonzini serial_inited = 1; 91f366255fSPaolo Bonzini } 927d36db35SAvi Kivity 93f366255fSPaolo Bonzini for (i = 0; i < len; i++) { 94f366255fSPaolo Bonzini serial_outb(buf[i]); 95f366255fSPaolo Bonzini } 96f366255fSPaolo Bonzini #else 975edbb9aeSPaolo Bonzini asm volatile ("addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1)); 98f366255fSPaolo Bonzini #endif 997d36db35SAvi Kivity } 1007d36db35SAvi Kivity 101b5105e8bSPaolo Bonzini static void print_serial_u32(u32 value) 102b5105e8bSPaolo Bonzini { 103b5105e8bSPaolo Bonzini char n[12], *p; 104b5105e8bSPaolo Bonzini p = &n[11]; 105b5105e8bSPaolo Bonzini *p = 0; 106b5105e8bSPaolo Bonzini do { 107b5105e8bSPaolo Bonzini *--p = '0' + (value % 10); 108b5105e8bSPaolo Bonzini value /= 10; 109b5105e8bSPaolo Bonzini } while (value > 0); 110b5105e8bSPaolo Bonzini print_serial(p); 111b5105e8bSPaolo Bonzini } 112b5105e8bSPaolo Bonzini 113b393fe28SNadav Amit static int failed; 114b393fe28SNadav Amit 1157d36db35SAvi Kivity static void exit(int code) 1167d36db35SAvi Kivity { 117f366255fSPaolo Bonzini outb(code, 0xf4); 1187d36db35SAvi Kivity } 1197d36db35SAvi Kivity 1207d36db35SAvi Kivity struct regs { 1217d36db35SAvi Kivity u32 eax, ebx, ecx, edx; 1227d36db35SAvi Kivity u32 esi, edi, esp, ebp; 1237d36db35SAvi Kivity u32 eip, eflags; 1247d36db35SAvi Kivity }; 1257d36db35SAvi Kivity 126975ca087SPeter Feiner struct table_descr { 127975ca087SPeter Feiner u16 limit; 128975ca087SPeter Feiner void *base; 129975ca087SPeter Feiner } __attribute__((packed)); 130975ca087SPeter Feiner 1317d36db35SAvi Kivity static u64 gdt[] = { 1327d36db35SAvi Kivity 0, 1337d36db35SAvi Kivity 0x00cf9b000000ffffull, // flat 32-bit code segment 1347d36db35SAvi Kivity 0x00cf93000000ffffull, // flat 32-bit data segment 1357d36db35SAvi Kivity }; 1367d36db35SAvi Kivity 137975ca087SPeter Feiner static struct table_descr gdt_descr = { 1387d36db35SAvi Kivity sizeof(gdt) - 1, 1397d36db35SAvi Kivity gdt, 1407d36db35SAvi Kivity }; 1417d36db35SAvi Kivity 142d4dc402cSAvi Kivity struct insn_desc { 143d4dc402cSAvi Kivity u16 ptr; 144d4dc402cSAvi Kivity u16 len; 145d4dc402cSAvi Kivity }; 146d4dc402cSAvi Kivity 147bd62e289SBill Wendling struct { 148bd62e289SBill Wendling u32 stack[128]; 149bd62e289SBill Wendling char top[]; 150bd62e289SBill Wendling } tmp_stack; 151bd62e289SBill Wendling 15218253fdeSAvi Kivity static struct regs inregs, outregs; 15318253fdeSAvi Kivity 154bd62e289SBill Wendling static inline void init_inregs(struct regs *regs) 155bd62e289SBill Wendling { 156bd62e289SBill Wendling inregs = (struct regs){ 0 }; 157bd62e289SBill Wendling if (regs) 158bd62e289SBill Wendling inregs = *regs; 159bd62e289SBill Wendling if (!inregs.esp) 160bd62e289SBill Wendling inregs.esp = (unsigned long)&tmp_stack.top; 161bd62e289SBill Wendling } 162bd62e289SBill Wendling 16318253fdeSAvi Kivity static void exec_in_big_real_mode(struct insn_desc *insn) 1647d36db35SAvi Kivity { 1657d36db35SAvi Kivity unsigned long tmp; 1667d36db35SAvi Kivity static struct regs save; 1677d36db35SAvi Kivity int i; 1687d36db35SAvi Kivity extern u8 test_insn[], test_insn_end[]; 1697d36db35SAvi Kivity 170d4dc402cSAvi Kivity for (i = 0; i < insn->len; ++i) 171d4dc402cSAvi Kivity test_insn[i] = ((u8 *)(unsigned long)insn->ptr)[i]; 1727d36db35SAvi Kivity for (; i < test_insn_end - test_insn; ++i) 1737d36db35SAvi Kivity test_insn[i] = 0x90; // nop 1747d36db35SAvi Kivity 17518253fdeSAvi Kivity save = inregs; 1767d36db35SAvi Kivity asm volatile( 1777d36db35SAvi Kivity "lgdtl %[gdt_descr] \n\t" 1787d36db35SAvi Kivity "mov %%cr0, %[tmp] \n\t" 1797d36db35SAvi Kivity "or $1, %[tmp] \n\t" 1807d36db35SAvi Kivity "mov %[tmp], %%cr0 \n\t" 1817d36db35SAvi Kivity "mov %[bigseg], %%gs \n\t" 1827d36db35SAvi Kivity "and $-2, %[tmp] \n\t" 1837d36db35SAvi Kivity "mov %[tmp], %%cr0 \n\t" 1847d36db35SAvi Kivity 185eb6687a2SBill Wendling /* Save ES, because it is clobbered by some tests. */ 186eb6687a2SBill Wendling "pushw %%es \n\t" 187eb6687a2SBill Wendling 18832001692SAvi Kivity "pushw %[save]+36; popfw \n\t" 1897d36db35SAvi Kivity "xchg %%eax, %[save]+0 \n\t" 1907d36db35SAvi Kivity "xchg %%ebx, %[save]+4 \n\t" 1917d36db35SAvi Kivity "xchg %%ecx, %[save]+8 \n\t" 1927d36db35SAvi Kivity "xchg %%edx, %[save]+12 \n\t" 1937d36db35SAvi Kivity "xchg %%esi, %[save]+16 \n\t" 1947d36db35SAvi Kivity "xchg %%edi, %[save]+20 \n\t" 1957d36db35SAvi Kivity "xchg %%esp, %[save]+24 \n\t" 1967d36db35SAvi Kivity "xchg %%ebp, %[save]+28 \n\t" 1977d36db35SAvi Kivity 1987d36db35SAvi Kivity "test_insn: . = . + 32\n\t" 1997d36db35SAvi Kivity "test_insn_end: \n\t" 2007d36db35SAvi Kivity 2017d36db35SAvi Kivity "xchg %%eax, %[save]+0 \n\t" 2027d36db35SAvi Kivity "xchg %%ebx, %[save]+4 \n\t" 2037d36db35SAvi Kivity "xchg %%ecx, %[save]+8 \n\t" 2047d36db35SAvi Kivity "xchg %%edx, %[save]+12 \n\t" 2057d36db35SAvi Kivity "xchg %%esi, %[save]+16 \n\t" 2067d36db35SAvi Kivity "xchg %%edi, %[save]+20 \n\t" 2077d36db35SAvi Kivity "xchg %%esp, %[save]+24 \n\t" 2087d36db35SAvi Kivity "xchg %%ebp, %[save]+28 \n\t" 2097d36db35SAvi Kivity 2107d36db35SAvi Kivity /* Save EFLAGS in outregs*/ 2117d36db35SAvi Kivity "pushfl \n\t" 2127d36db35SAvi Kivity "popl %[save]+36 \n\t" 2137d36db35SAvi Kivity 214eb6687a2SBill Wendling /* Restore ES for future rep string operations. */ 215eb6687a2SBill Wendling "popw %%es \n\t" 216eb6687a2SBill Wendling 2175edbb9aeSPaolo Bonzini /* Restore DF for the harness code */ 2185edbb9aeSPaolo Bonzini "cld\n\t" 2197d36db35SAvi Kivity "xor %[tmp], %[tmp] \n\t" 2207d36db35SAvi Kivity "mov %[tmp], %%gs \n\t" 2217d36db35SAvi Kivity : [tmp]"=&r"(tmp), [save]"+m"(save) 2227d36db35SAvi Kivity : [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16) 2237d36db35SAvi Kivity : "cc", "memory" 2247d36db35SAvi Kivity ); 22518253fdeSAvi Kivity outregs = save; 2267d36db35SAvi Kivity } 2277d36db35SAvi Kivity 2287d36db35SAvi Kivity #define R_AX 1 2297d36db35SAvi Kivity #define R_BX 2 2307d36db35SAvi Kivity #define R_CX 4 2317d36db35SAvi Kivity #define R_DX 8 2327d36db35SAvi Kivity #define R_SI 16 2337d36db35SAvi Kivity #define R_DI 32 2347d36db35SAvi Kivity #define R_SP 64 2357d36db35SAvi Kivity #define R_BP 128 2367d36db35SAvi Kivity 2372e3f9f1fSThomas Huth static int regs_equal(int ignore) 2387d36db35SAvi Kivity { 23918253fdeSAvi Kivity const u32 *p1 = &inregs.eax, *p2 = &outregs.eax; // yuck 2407d36db35SAvi Kivity int i; 2417d36db35SAvi Kivity 2427d36db35SAvi Kivity for (i = 0; i < 8; ++i) 2437d36db35SAvi Kivity if (!(ignore & (1 << i)) && p1[i] != p2[i]) 2447d36db35SAvi Kivity return 0; 2457d36db35SAvi Kivity return 1; 2467d36db35SAvi Kivity } 2477d36db35SAvi Kivity 2486055ea1fSAvi Kivity static void report(const char *name, u16 regs_ignore, _Bool ok) 24981050840SAvi Kivity { 2506055ea1fSAvi Kivity if (!regs_equal(regs_ignore)) { 2516055ea1fSAvi Kivity ok = 0; 2526055ea1fSAvi Kivity } 25381050840SAvi Kivity print_serial(ok ? "PASS: " : "FAIL: "); 25481050840SAvi Kivity print_serial(name); 25581050840SAvi Kivity print_serial("\n"); 256b393fe28SNadav Amit if (!ok) 257b393fe28SNadav Amit failed = 1; 25881050840SAvi Kivity } 25981050840SAvi Kivity 2607d36db35SAvi Kivity #define MK_INSN(name, str) \ 2617d36db35SAvi Kivity asm ( \ 262d4dc402cSAvi Kivity ".pushsection .data.insn \n\t" \ 263d4dc402cSAvi Kivity "insn_" #name ": \n\t" \ 264d4dc402cSAvi Kivity ".word 1001f, 1002f - 1001f \n\t" \ 265d4dc402cSAvi Kivity ".popsection \n\t" \ 266d4dc402cSAvi Kivity ".pushsection .text.insn, \"ax\" \n\t" \ 267d4dc402cSAvi Kivity "1001: \n\t" \ 268d4dc402cSAvi Kivity "insn_code_" #name ": " str " \n\t" \ 269d4dc402cSAvi Kivity "1002: \n\t" \ 270d4dc402cSAvi Kivity ".popsection" \ 2717d36db35SAvi Kivity ); \ 272d4dc402cSAvi Kivity extern struct insn_desc insn_##name; 2737d36db35SAvi Kivity 2742e3f9f1fSThomas Huth static void test_xchg(void) 2757d36db35SAvi Kivity { 2767d36db35SAvi Kivity MK_INSN(xchg_test1, "xchg %eax,%eax\n\t"); 2777d36db35SAvi Kivity MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t"); 2787d36db35SAvi Kivity MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t"); 2797d36db35SAvi Kivity MK_INSN(xchg_test4, "xchg %eax,%edx\n\t"); 2807d36db35SAvi Kivity MK_INSN(xchg_test5, "xchg %eax,%esi\n\t"); 2817d36db35SAvi Kivity MK_INSN(xchg_test6, "xchg %eax,%edi\n\t"); 2827d36db35SAvi Kivity MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t"); 2837d36db35SAvi Kivity MK_INSN(xchg_test8, "xchg %eax,%esp\n\t"); 2847d36db35SAvi Kivity 28518253fdeSAvi Kivity inregs = (struct regs){ .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}; 2867d36db35SAvi Kivity 28718253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test1); 2886055ea1fSAvi Kivity report("xchg 1", 0, 1); 28918253fdeSAvi Kivity 29018253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test2); 2916055ea1fSAvi Kivity report("xchg 2", R_AX | R_BX, 2926055ea1fSAvi Kivity outregs.eax == inregs.ebx && outregs.ebx == inregs.eax); 2937d36db35SAvi Kivity 29418253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test3); 2956055ea1fSAvi Kivity report("xchg 3", R_AX | R_CX, 2966055ea1fSAvi Kivity outregs.eax == inregs.ecx && outregs.ecx == inregs.eax); 2977d36db35SAvi Kivity 29818253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test4); 2996055ea1fSAvi Kivity report("xchg 4", R_AX | R_DX, 3006055ea1fSAvi Kivity outregs.eax == inregs.edx && outregs.edx == inregs.eax); 3017d36db35SAvi Kivity 30218253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test5); 3036055ea1fSAvi Kivity report("xchg 5", R_AX | R_SI, 3046055ea1fSAvi Kivity outregs.eax == inregs.esi && outregs.esi == inregs.eax); 3057d36db35SAvi Kivity 30618253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test6); 3076055ea1fSAvi Kivity report("xchg 6", R_AX | R_DI, 3086055ea1fSAvi Kivity outregs.eax == inregs.edi && outregs.edi == inregs.eax); 3097d36db35SAvi Kivity 31018253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test7); 3116055ea1fSAvi Kivity report("xchg 7", R_AX | R_BP, 3126055ea1fSAvi Kivity outregs.eax == inregs.ebp && outregs.ebp == inregs.eax); 3137d36db35SAvi Kivity 31418253fdeSAvi Kivity exec_in_big_real_mode(&insn_xchg_test8); 3156055ea1fSAvi Kivity report("xchg 8", R_AX | R_SP, 3166055ea1fSAvi Kivity outregs.eax == inregs.esp && outregs.esp == inregs.eax); 3177d36db35SAvi Kivity } 3187d36db35SAvi Kivity 3192e3f9f1fSThomas Huth static void test_shld(void) 3207d36db35SAvi Kivity { 3217d36db35SAvi Kivity MK_INSN(shld_test, "shld $8,%edx,%eax\n\t"); 3227d36db35SAvi Kivity 323bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0xbe, .edx = 0xef000000 }); 324bd62e289SBill Wendling 32518253fdeSAvi Kivity exec_in_big_real_mode(&insn_shld_test); 3266055ea1fSAvi Kivity report("shld", ~0, outregs.eax == 0xbeef); 3277d36db35SAvi Kivity } 3287d36db35SAvi Kivity 3292e3f9f1fSThomas Huth static void test_mov_imm(void) 3307d36db35SAvi Kivity { 3317d36db35SAvi Kivity MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax"); 3327d36db35SAvi Kivity MK_INSN(mov_r16_imm_1, "mov $1234, %ax"); 3337d36db35SAvi Kivity MK_INSN(mov_r8_imm_1, "mov $0x12, %ah"); 3347d36db35SAvi Kivity MK_INSN(mov_r8_imm_2, "mov $0x34, %al"); 3357d36db35SAvi Kivity MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t"); 3367d36db35SAvi Kivity 337bd62e289SBill Wendling init_inregs(NULL); 33818253fdeSAvi Kivity 33918253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r16_imm_1); 3406055ea1fSAvi Kivity report("mov 1", R_AX, outregs.eax == 1234); 3417d36db35SAvi Kivity 3427d36db35SAvi Kivity /* test mov $imm, %eax */ 34318253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r32_imm_1); 3446055ea1fSAvi Kivity report("mov 2", R_AX, outregs.eax == 1234567890); 3457d36db35SAvi Kivity 3467d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 34718253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r8_imm_1); 3486055ea1fSAvi Kivity report("mov 3", R_AX, outregs.eax == 0x1200); 3497d36db35SAvi Kivity 35018253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r8_imm_2); 3516055ea1fSAvi Kivity report("mov 4", R_AX, outregs.eax == 0x34); 3527d36db35SAvi Kivity 35318253fdeSAvi Kivity exec_in_big_real_mode(&insn_mov_r8_imm_3); 3546055ea1fSAvi Kivity report("mov 5", R_AX, outregs.eax == 0x1234); 3557d36db35SAvi Kivity } 3567d36db35SAvi Kivity 3572e3f9f1fSThomas Huth static void test_sub_imm(void) 3587d36db35SAvi Kivity { 3597d36db35SAvi Kivity MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t"); 3607d36db35SAvi Kivity MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t"); 3617d36db35SAvi Kivity MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t"); 3627d36db35SAvi Kivity MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t"); 3637d36db35SAvi Kivity 364bd62e289SBill Wendling init_inregs(NULL); 36518253fdeSAvi Kivity 36618253fdeSAvi Kivity exec_in_big_real_mode(&insn_sub_r16_imm_1); 3676055ea1fSAvi Kivity report("sub 1", R_AX, outregs.eax == 1224); 3687d36db35SAvi Kivity 3697d36db35SAvi Kivity /* test mov $imm, %eax */ 37018253fdeSAvi Kivity exec_in_big_real_mode(&insn_sub_r32_imm_1); 3716055ea1fSAvi Kivity report("sub 2", R_AX, outregs.eax == 1234567880); 3727d36db35SAvi Kivity 3737d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 37418253fdeSAvi Kivity exec_in_big_real_mode(&insn_sub_r8_imm_1); 3756055ea1fSAvi Kivity report("sub 3", R_AX, outregs.eax == 0x0200); 3767d36db35SAvi Kivity 37718253fdeSAvi Kivity exec_in_big_real_mode(&insn_sub_r8_imm_2); 3786055ea1fSAvi Kivity report("sub 4", R_AX, outregs.eax == 0x24); 3797d36db35SAvi Kivity } 3807d36db35SAvi Kivity 3812e3f9f1fSThomas Huth static void test_xor_imm(void) 3827d36db35SAvi Kivity { 3837d36db35SAvi Kivity MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t"); 3847d36db35SAvi Kivity MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t"); 3857d36db35SAvi Kivity MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t"); 3867d36db35SAvi Kivity MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t"); 3877d36db35SAvi Kivity 388bd62e289SBill Wendling init_inregs(NULL); 38918253fdeSAvi Kivity 39018253fdeSAvi Kivity exec_in_big_real_mode(&insn_xor_r16_imm_1); 3916055ea1fSAvi Kivity report("xor 1", R_AX, outregs.eax == 0); 3927d36db35SAvi Kivity 3937d36db35SAvi Kivity /* test mov $imm, %eax */ 39418253fdeSAvi Kivity exec_in_big_real_mode(&insn_xor_r32_imm_1); 3956055ea1fSAvi Kivity report("xor 2", R_AX, outregs.eax == 0); 3967d36db35SAvi Kivity 3977d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 39818253fdeSAvi Kivity exec_in_big_real_mode(&insn_xor_r8_imm_1); 3996055ea1fSAvi Kivity report("xor 3", R_AX, outregs.eax == 0); 4007d36db35SAvi Kivity 40118253fdeSAvi Kivity exec_in_big_real_mode(&insn_xor_r8_imm_2); 4026055ea1fSAvi Kivity report("xor 4", R_AX, outregs.eax == 0); 4037d36db35SAvi Kivity } 4047d36db35SAvi Kivity 4052e3f9f1fSThomas Huth static void test_cmp_imm(void) 4067d36db35SAvi Kivity { 4077d36db35SAvi Kivity MK_INSN(cmp_test1, "mov $0x34, %al\n\t" 4087d36db35SAvi Kivity "cmp $0x34, %al\n\t"); 4097d36db35SAvi Kivity MK_INSN(cmp_test2, "mov $0x34, %al\n\t" 4107d36db35SAvi Kivity "cmp $0x39, %al\n\t"); 4117d36db35SAvi Kivity MK_INSN(cmp_test3, "mov $0x34, %al\n\t" 4127d36db35SAvi Kivity "cmp $0x24, %al\n\t"); 4137d36db35SAvi Kivity 414bd62e289SBill Wendling init_inregs(NULL); 41518253fdeSAvi Kivity 4167d36db35SAvi Kivity /* test cmp imm8 with AL */ 4177d36db35SAvi Kivity /* ZF: (bit 6) Zero Flag becomes 1 if an operation results 4187d36db35SAvi Kivity * in a 0 writeback, or 0 register 4197d36db35SAvi Kivity */ 42018253fdeSAvi Kivity exec_in_big_real_mode(&insn_cmp_test1); 4216055ea1fSAvi Kivity report("cmp 1", ~0, (outregs.eflags & (1<<6)) == (1<<6)); 4227d36db35SAvi Kivity 42318253fdeSAvi Kivity exec_in_big_real_mode(&insn_cmp_test2); 4246055ea1fSAvi Kivity report("cmp 2", ~0, (outregs.eflags & (1<<6)) == 0); 4257d36db35SAvi Kivity 42618253fdeSAvi Kivity exec_in_big_real_mode(&insn_cmp_test3); 4276055ea1fSAvi Kivity report("cmp 3", ~0, (outregs.eflags & (1<<6)) == 0); 4287d36db35SAvi Kivity } 4297d36db35SAvi Kivity 4302e3f9f1fSThomas Huth static void test_add_imm(void) 4317d36db35SAvi Kivity { 4327d36db35SAvi Kivity MK_INSN(add_test1, "mov $0x43211234, %eax \n\t" 4337d36db35SAvi Kivity "add $0x12344321, %eax \n\t"); 4347d36db35SAvi Kivity MK_INSN(add_test2, "mov $0x12, %eax \n\t" 4357d36db35SAvi Kivity "add $0x21, %al\n\t"); 4367d36db35SAvi Kivity 437bd62e289SBill Wendling init_inregs(NULL); 43818253fdeSAvi Kivity 43918253fdeSAvi Kivity exec_in_big_real_mode(&insn_add_test1); 4406055ea1fSAvi Kivity report("add 1", ~0, outregs.eax == 0x55555555); 4417d36db35SAvi Kivity 44218253fdeSAvi Kivity exec_in_big_real_mode(&insn_add_test2); 4436055ea1fSAvi Kivity report("add 2", ~0, outregs.eax == 0x33); 4447d36db35SAvi Kivity } 4457d36db35SAvi Kivity 4462e3f9f1fSThomas Huth static void test_eflags_insn(void) 4477d36db35SAvi Kivity { 4487d36db35SAvi Kivity MK_INSN(clc, "clc"); 449b3261e48SMohammed Gamal MK_INSN(stc, "stc"); 4507d36db35SAvi Kivity MK_INSN(cli, "cli"); 4517d36db35SAvi Kivity MK_INSN(sti, "sti"); 4527d36db35SAvi Kivity MK_INSN(cld, "cld"); 4537d36db35SAvi Kivity MK_INSN(std, "std"); 4547d36db35SAvi Kivity 455bd62e289SBill Wendling init_inregs(NULL); 45618253fdeSAvi Kivity 45718253fdeSAvi Kivity exec_in_big_real_mode(&insn_clc); 4586055ea1fSAvi Kivity report("clc", ~0, (outregs.eflags & 1) == 0); 4597d36db35SAvi Kivity 46018253fdeSAvi Kivity exec_in_big_real_mode(&insn_stc); 4616055ea1fSAvi Kivity report("stc", ~0, (outregs.eflags & 1) == 1); 462b3261e48SMohammed Gamal 46318253fdeSAvi Kivity exec_in_big_real_mode(&insn_cli); 4646055ea1fSAvi Kivity report("cli", ~0, !(outregs.eflags & (1 << 9))); 4657d36db35SAvi Kivity 46618253fdeSAvi Kivity exec_in_big_real_mode(&insn_sti); 4676055ea1fSAvi Kivity report("sti", ~0, outregs.eflags & (1 << 9)); 4687d36db35SAvi Kivity 46918253fdeSAvi Kivity exec_in_big_real_mode(&insn_cld); 4706055ea1fSAvi Kivity report("cld", ~0, !(outregs.eflags & (1 << 10))); 4717d36db35SAvi Kivity 47218253fdeSAvi Kivity exec_in_big_real_mode(&insn_std); 4736055ea1fSAvi Kivity report("std", ~0, (outregs.eflags & (1 << 10))); 4747d36db35SAvi Kivity } 4757d36db35SAvi Kivity 4762e3f9f1fSThomas Huth static void test_io(void) 4777d36db35SAvi Kivity { 4787d36db35SAvi Kivity MK_INSN(io_test1, "mov $0xff, %al \n\t" 4797d36db35SAvi Kivity "out %al, $0xe0 \n\t" 4807d36db35SAvi Kivity "mov $0x00, %al \n\t" 4817d36db35SAvi Kivity "in $0xe0, %al \n\t"); 4827d36db35SAvi Kivity MK_INSN(io_test2, "mov $0xffff, %ax \n\t" 4837d36db35SAvi Kivity "out %ax, $0xe0 \n\t" 4847d36db35SAvi Kivity "mov $0x0000, %ax \n\t" 4857d36db35SAvi Kivity "in $0xe0, %ax \n\t"); 4867d36db35SAvi Kivity MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t" 4877d36db35SAvi Kivity "out %eax, $0xe0 \n\t" 4887d36db35SAvi Kivity "mov $0x000000, %eax \n\t" 4897d36db35SAvi Kivity "in $0xe0, %eax \n\t"); 4907d36db35SAvi Kivity MK_INSN(io_test4, "mov $0xe0, %dx \n\t" 4917d36db35SAvi Kivity "mov $0xff, %al \n\t" 4927d36db35SAvi Kivity "out %al, %dx \n\t" 4937d36db35SAvi Kivity "mov $0x00, %al \n\t" 4947d36db35SAvi Kivity "in %dx, %al \n\t"); 4957d36db35SAvi Kivity MK_INSN(io_test5, "mov $0xe0, %dx \n\t" 4967d36db35SAvi Kivity "mov $0xffff, %ax \n\t" 4977d36db35SAvi Kivity "out %ax, %dx \n\t" 4987d36db35SAvi Kivity "mov $0x0000, %ax \n\t" 4997d36db35SAvi Kivity "in %dx, %ax \n\t"); 5007d36db35SAvi Kivity MK_INSN(io_test6, "mov $0xe0, %dx \n\t" 5017d36db35SAvi Kivity "mov $0xffffffff, %eax \n\t" 5027d36db35SAvi Kivity "out %eax, %dx \n\t" 5037d36db35SAvi Kivity "mov $0x00000000, %eax \n\t" 5047d36db35SAvi Kivity "in %dx, %eax \n\t"); 5057d36db35SAvi Kivity 506bd62e289SBill Wendling init_inregs(NULL); 50718253fdeSAvi Kivity 50818253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test1); 5096055ea1fSAvi Kivity report("pio 1", R_AX, outregs.eax == 0xff); 5107d36db35SAvi Kivity 51118253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test2); 5126055ea1fSAvi Kivity report("pio 2", R_AX, outregs.eax == 0xffff); 5137d36db35SAvi Kivity 51418253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test3); 5156055ea1fSAvi Kivity report("pio 3", R_AX, outregs.eax == 0xffffffff); 5167d36db35SAvi Kivity 51718253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test4); 5186055ea1fSAvi Kivity report("pio 4", R_AX|R_DX, outregs.eax == 0xff); 5197d36db35SAvi Kivity 52018253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test5); 5216055ea1fSAvi Kivity report("pio 5", R_AX|R_DX, outregs.eax == 0xffff); 5227d36db35SAvi Kivity 52318253fdeSAvi Kivity exec_in_big_real_mode(&insn_io_test6); 5246055ea1fSAvi Kivity report("pio 6", R_AX|R_DX, outregs.eax == 0xffffffff); 5257d36db35SAvi Kivity } 5267d36db35SAvi Kivity 527c0b7268dSAvi Kivity asm ("retf: lretw"); 5282e3f9f1fSThomas Huth extern void retf(void); 529c0b7268dSAvi Kivity 5304f66bc86SBruce Rogers asm ("retf_imm: lretw $10"); 5312e3f9f1fSThomas Huth extern void retf_imm(void); 5324f66bc86SBruce Rogers 5332e3f9f1fSThomas Huth static void test_call(void) 5347d36db35SAvi Kivity { 535c0b7268dSAvi Kivity u32 addr; 5367d36db35SAvi Kivity 5377d36db35SAvi Kivity MK_INSN(call1, "mov $test_function, %eax \n\t" 5387d36db35SAvi Kivity "call *%eax\n\t"); 5397d36db35SAvi Kivity MK_INSN(call_near1, "jmp 2f\n\t" 5407d36db35SAvi Kivity "1: mov $0x1234, %eax\n\t" 5417d36db35SAvi Kivity "ret\n\t" 5427d36db35SAvi Kivity "2: call 1b\t"); 5437d36db35SAvi Kivity MK_INSN(call_near2, "call 1f\n\t" 5447d36db35SAvi Kivity "jmp 2f\n\t" 5457d36db35SAvi Kivity "1: mov $0x1234, %eax\n\t" 5467d36db35SAvi Kivity "ret\n\t" 5477d36db35SAvi Kivity "2:\t"); 548c0b7268dSAvi Kivity MK_INSN(call_far1, "lcallw *(%ebx)\n\t"); 549556d2680SWei Yongjun MK_INSN(call_far2, "lcallw $0, $retf\n\t"); 550c6061817SAvi Kivity MK_INSN(ret_imm, "sub $10, %sp; jmp 2f; 1: retw $10; 2: callw 1b"); 5514f66bc86SBruce Rogers MK_INSN(retf_imm, "sub $10, %sp; lcallw $0, $retf_imm"); 5527d36db35SAvi Kivity 553bd62e289SBill Wendling init_inregs(NULL); 554bd62e289SBill Wendling 55518253fdeSAvi Kivity exec_in_big_real_mode(&insn_call1); 5566055ea1fSAvi Kivity report("call 1", R_AX, outregs.eax == 0x1234); 5577d36db35SAvi Kivity 55818253fdeSAvi Kivity exec_in_big_real_mode(&insn_call_near1); 5596055ea1fSAvi Kivity report("call near 1", R_AX, outregs.eax == 0x1234); 5607d36db35SAvi Kivity 56118253fdeSAvi Kivity exec_in_big_real_mode(&insn_call_near2); 5626055ea1fSAvi Kivity report("call near 2", R_AX, outregs.eax == 0x1234); 563c0b7268dSAvi Kivity 564c0b7268dSAvi Kivity addr = (((unsigned)retf >> 4) << 16) | ((unsigned)retf & 0x0f); 565c0b7268dSAvi Kivity inregs.ebx = (unsigned)&addr; 56618253fdeSAvi Kivity exec_in_big_real_mode(&insn_call_far1); 5676055ea1fSAvi Kivity report("call far 1", 0, 1); 568c6061817SAvi Kivity 569556d2680SWei Yongjun exec_in_big_real_mode(&insn_call_far2); 570556d2680SWei Yongjun report("call far 2", 0, 1); 571556d2680SWei Yongjun 57218253fdeSAvi Kivity exec_in_big_real_mode(&insn_ret_imm); 5736055ea1fSAvi Kivity report("ret imm 1", 0, 1); 5744f66bc86SBruce Rogers 5754f66bc86SBruce Rogers exec_in_big_real_mode(&insn_retf_imm); 5764f66bc86SBruce Rogers report("retf imm 1", 0, 1); 5777d36db35SAvi Kivity } 5787d36db35SAvi Kivity 5792e3f9f1fSThomas Huth static void test_jcc_short(void) 5807d36db35SAvi Kivity { 5817d36db35SAvi Kivity MK_INSN(jnz_short1, "jnz 1f\n\t" 5827d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 5837d36db35SAvi Kivity "1:\n\t"); 5847d36db35SAvi Kivity MK_INSN(jnz_short2, "1:\n\t" 5857d36db35SAvi Kivity "cmp $0x1234, %eax\n\t" 5867d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 5877d36db35SAvi Kivity "jnz 1b\n\t"); 5887d36db35SAvi Kivity MK_INSN(jmp_short1, "jmp 1f\n\t" 5897d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 5907d36db35SAvi Kivity "1:\n\t"); 5917d36db35SAvi Kivity 592bd62e289SBill Wendling init_inregs(NULL); 5937d36db35SAvi Kivity 59418253fdeSAvi Kivity exec_in_big_real_mode(&insn_jnz_short1); 5956055ea1fSAvi Kivity report("jnz short 1", ~0, 1); 59618253fdeSAvi Kivity 59718253fdeSAvi Kivity exec_in_big_real_mode(&insn_jnz_short2); 5986055ea1fSAvi Kivity report("jnz short 2", R_AX, (outregs.eflags & (1 << 6))); 5997d36db35SAvi Kivity 60018253fdeSAvi Kivity exec_in_big_real_mode(&insn_jmp_short1); 6016055ea1fSAvi Kivity report("jmp short 1", ~0, 1); 6027d36db35SAvi Kivity } 6037d36db35SAvi Kivity 6042e3f9f1fSThomas Huth static void test_jcc_near(void) 6057d36db35SAvi Kivity { 6067d36db35SAvi Kivity /* encode near jmp manually. gas will not do it if offsets < 127 byte */ 6077d36db35SAvi Kivity MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t" 6087d36db35SAvi Kivity "mov $0x1234, %eax\n\t"); 6097d36db35SAvi Kivity MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t" 6107d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6117d36db35SAvi Kivity ".byte 0x0f, 0x85, 0xf0, 0xff\n\t"); 6127d36db35SAvi Kivity MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t" 6137d36db35SAvi Kivity "mov $0x1234, %eax\n\t"); 6147d36db35SAvi Kivity 615bd62e289SBill Wendling init_inregs(NULL); 6167d36db35SAvi Kivity 61718253fdeSAvi Kivity exec_in_big_real_mode(&insn_jnz_near1); 6186055ea1fSAvi Kivity report("jnz near 1", 0, 1); 61918253fdeSAvi Kivity 62018253fdeSAvi Kivity exec_in_big_real_mode(&insn_jnz_near2); 6216055ea1fSAvi Kivity report("jnz near 2", R_AX, outregs.eflags & (1 << 6)); 6227d36db35SAvi Kivity 62318253fdeSAvi Kivity exec_in_big_real_mode(&insn_jmp_near1); 6246055ea1fSAvi Kivity report("jmp near 1", 0, 1); 6257d36db35SAvi Kivity } 6267d36db35SAvi Kivity 6272e3f9f1fSThomas Huth static void test_long_jmp(void) 6287d36db35SAvi Kivity { 6297d36db35SAvi Kivity MK_INSN(long_jmp, "call 1f\n\t" 6307d36db35SAvi Kivity "jmp 2f\n\t" 6317d36db35SAvi Kivity "1: jmp $0, $test_function\n\t" 6327d36db35SAvi Kivity "2:\n\t"); 633bd62e289SBill Wendling 634bd62e289SBill Wendling init_inregs(NULL); 635bd62e289SBill Wendling 63618253fdeSAvi Kivity exec_in_big_real_mode(&insn_long_jmp); 6376055ea1fSAvi Kivity report("jmp far 1", R_AX, outregs.eax == 0x1234); 6387d36db35SAvi Kivity } 639fa74f8a6SMohammed Gamal 6402e3f9f1fSThomas Huth static void test_push_pop(void) 6417d36db35SAvi Kivity { 6427d36db35SAvi Kivity MK_INSN(push32, "mov $0x12345678, %eax\n\t" 6437d36db35SAvi Kivity "push %eax\n\t" 6447d36db35SAvi Kivity "pop %ebx\n\t"); 6457d36db35SAvi Kivity MK_INSN(push16, "mov $0x1234, %ax\n\t" 6467d36db35SAvi Kivity "push %ax\n\t" 6477d36db35SAvi Kivity "pop %bx\n\t"); 6487d36db35SAvi Kivity 6497d36db35SAvi Kivity MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten 6507d36db35SAvi Kivity "mov $0x123, %ax\n\t" 6517d36db35SAvi Kivity "mov %ax, %es\n\t" 652*231b4c3bSRoman Bolshakov "pushw %es\n\t" 6537d36db35SAvi Kivity "pop %bx \n\t" 6547d36db35SAvi Kivity ); 6557d36db35SAvi Kivity MK_INSN(pop_es, "push %ax\n\t" 656*231b4c3bSRoman Bolshakov "popw %es\n\t" 6577d36db35SAvi Kivity "mov %es, %bx\n\t" 6587d36db35SAvi Kivity ); 659*231b4c3bSRoman Bolshakov MK_INSN(push_pop_ss, "pushw %ss\n\t" 6607d36db35SAvi Kivity "pushw %ax\n\t" 6617d36db35SAvi Kivity "popw %ss\n\t" 6627d36db35SAvi Kivity "mov %ss, %bx\n\t" 663*231b4c3bSRoman Bolshakov "popw %ss\n\t" 6647d36db35SAvi Kivity ); 665*231b4c3bSRoman Bolshakov MK_INSN(push_pop_fs, "pushl %fs\n\t" 6667d36db35SAvi Kivity "pushl %eax\n\t" 6677d36db35SAvi Kivity "popl %fs\n\t" 6687d36db35SAvi Kivity "mov %fs, %ebx\n\t" 669*231b4c3bSRoman Bolshakov "popl %fs\n\t" 6707d36db35SAvi Kivity ); 67109b657b6SAvi Kivity MK_INSN(push_pop_high_esp_bits, 67209b657b6SAvi Kivity "xor $0x12340000, %esp \n\t" 67309b657b6SAvi Kivity "push %ax; \n\t" 67409b657b6SAvi Kivity "xor $0x12340000, %esp \n\t" 67509b657b6SAvi Kivity "pop %bx"); 6767d36db35SAvi Kivity 677bd62e289SBill Wendling init_inregs(NULL); 67818253fdeSAvi Kivity 67918253fdeSAvi Kivity exec_in_big_real_mode(&insn_push32); 6806055ea1fSAvi Kivity report("push/pop 1", R_AX|R_BX, 6816055ea1fSAvi Kivity outregs.eax == outregs.ebx && outregs.eax == 0x12345678); 6827d36db35SAvi Kivity 68318253fdeSAvi Kivity exec_in_big_real_mode(&insn_push16); 6846055ea1fSAvi Kivity report("push/pop 2", R_AX|R_BX, 6856055ea1fSAvi Kivity outregs.eax == outregs.ebx && outregs.eax == 0x1234); 6867d36db35SAvi Kivity 68718253fdeSAvi Kivity exec_in_big_real_mode(&insn_push_es); 6886055ea1fSAvi Kivity report("push/pop 3", R_AX|R_BX, 6896055ea1fSAvi Kivity outregs.ebx == outregs.eax && outregs.eax == 0x123); 6907d36db35SAvi Kivity 69118253fdeSAvi Kivity exec_in_big_real_mode(&insn_pop_es); 6926055ea1fSAvi Kivity report("push/pop 4", R_AX|R_BX, outregs.ebx == outregs.eax); 6937d36db35SAvi Kivity 69418253fdeSAvi Kivity exec_in_big_real_mode(&insn_push_pop_ss); 6956055ea1fSAvi Kivity report("push/pop 5", R_AX|R_BX, outregs.ebx == outregs.eax); 6967d36db35SAvi Kivity 69718253fdeSAvi Kivity exec_in_big_real_mode(&insn_push_pop_fs); 6986055ea1fSAvi Kivity report("push/pop 6", R_AX|R_BX, outregs.ebx == outregs.eax); 69909b657b6SAvi Kivity 70009b657b6SAvi Kivity inregs.eax = 0x9977; 70109b657b6SAvi Kivity inregs.ebx = 0x7799; 70209b657b6SAvi Kivity exec_in_big_real_mode(&insn_push_pop_high_esp_bits); 70309b657b6SAvi Kivity report("push/pop with high bits set in %esp", R_BX, outregs.ebx == 0x9977); 7047d36db35SAvi Kivity } 7057d36db35SAvi Kivity 7062e3f9f1fSThomas Huth static void test_null(void) 7077d36db35SAvi Kivity { 708d4dc402cSAvi Kivity MK_INSN(null, ""); 709d4dc402cSAvi Kivity 710bd62e289SBill Wendling init_inregs(NULL); 71118253fdeSAvi Kivity 71218253fdeSAvi Kivity exec_in_big_real_mode(&insn_null); 7136055ea1fSAvi Kivity report("null", 0, 1); 7147d36db35SAvi Kivity } 7157d36db35SAvi Kivity 7162e3f9f1fSThomas Huth static void test_pusha_popa(void) 7177d36db35SAvi Kivity { 7187d36db35SAvi Kivity MK_INSN(pusha, "pusha\n\t" 7197d36db35SAvi Kivity "pop %edi\n\t" 7207d36db35SAvi Kivity "pop %esi\n\t" 7217d36db35SAvi Kivity "pop %ebp\n\t" 7227d36db35SAvi Kivity "add $4, %esp\n\t" 7237d36db35SAvi Kivity "pop %ebx\n\t" 7247d36db35SAvi Kivity "pop %edx\n\t" 7257d36db35SAvi Kivity "pop %ecx\n\t" 7267d36db35SAvi Kivity "pop %eax\n\t" 7277d36db35SAvi Kivity ); 7287d36db35SAvi Kivity 7297d36db35SAvi Kivity MK_INSN(popa, "push %eax\n\t" 7307d36db35SAvi Kivity "push %ecx\n\t" 7317d36db35SAvi Kivity "push %edx\n\t" 7327d36db35SAvi Kivity "push %ebx\n\t" 7337d36db35SAvi Kivity "push %esp\n\t" 7347d36db35SAvi Kivity "push %ebp\n\t" 7357d36db35SAvi Kivity "push %esi\n\t" 7367d36db35SAvi Kivity "push %edi\n\t" 7377d36db35SAvi Kivity "popa\n\t" 7387d36db35SAvi Kivity ); 7397d36db35SAvi Kivity 740bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6 }); 7417d36db35SAvi Kivity 74218253fdeSAvi Kivity exec_in_big_real_mode(&insn_pusha); 7436055ea1fSAvi Kivity report("pusha/popa 1", 0, 1); 74418253fdeSAvi Kivity 74518253fdeSAvi Kivity exec_in_big_real_mode(&insn_popa); 7466055ea1fSAvi Kivity report("pusha/popa 1", 0, 1); 7477d36db35SAvi Kivity } 7487d36db35SAvi Kivity 7492e3f9f1fSThomas Huth static void test_iret(void) 7507d36db35SAvi Kivity { 7517d36db35SAvi Kivity MK_INSN(iret32, "pushf\n\t" 7527d36db35SAvi Kivity "pushl %cs\n\t" 7537d36db35SAvi Kivity "call 1f\n\t" /* a near call will push eip onto the stack */ 7547d36db35SAvi Kivity "jmp 2f\n\t" 755*231b4c3bSRoman Bolshakov "1: iretl\n\t" 7567d36db35SAvi Kivity "2:\n\t" 7577d36db35SAvi Kivity ); 7587d36db35SAvi Kivity 7597d36db35SAvi Kivity MK_INSN(iret16, "pushfw\n\t" 7607d36db35SAvi Kivity "pushw %cs\n\t" 7617d36db35SAvi Kivity "callw 1f\n\t" 7627d36db35SAvi Kivity "jmp 2f\n\t" 7637d36db35SAvi Kivity "1: iretw\n\t" 7647d36db35SAvi Kivity "2:\n\t"); 7657d36db35SAvi Kivity 7667d36db35SAvi Kivity MK_INSN(iret_flags32, "pushfl\n\t" 7677d36db35SAvi Kivity "popl %eax\n\t" 7687d36db35SAvi Kivity "andl $~0x2, %eax\n\t" 769964942e8SNadav Amit "orl $0xffc18028, %eax\n\t" 7707d36db35SAvi Kivity "pushl %eax\n\t" 7717d36db35SAvi Kivity "pushl %cs\n\t" 7727d36db35SAvi Kivity "call 1f\n\t" 7737d36db35SAvi Kivity "jmp 2f\n\t" 774*231b4c3bSRoman Bolshakov "1: iretl\n\t" 7757d36db35SAvi Kivity "2:\n\t"); 7767d36db35SAvi Kivity 7777d36db35SAvi Kivity MK_INSN(iret_flags16, "pushfw\n\t" 7787d36db35SAvi Kivity "popw %ax\n\t" 7797d36db35SAvi Kivity "and $~0x2, %ax\n\t" 7807d36db35SAvi Kivity "or $0x8028, %ax\n\t" 7817d36db35SAvi Kivity "pushw %ax\n\t" 7827d36db35SAvi Kivity "pushw %cs\n\t" 7837d36db35SAvi Kivity "callw 1f\n\t" 7847d36db35SAvi Kivity "jmp 2f\n\t" 7857d36db35SAvi Kivity "1: iretw\n\t" 7867d36db35SAvi Kivity "2:\n\t"); 7877d36db35SAvi Kivity 788bd62e289SBill Wendling init_inregs(NULL); 7897d36db35SAvi Kivity 79018253fdeSAvi Kivity exec_in_big_real_mode(&insn_iret32); 7916055ea1fSAvi Kivity report("iret 1", 0, 1); 7927d36db35SAvi Kivity 79318253fdeSAvi Kivity exec_in_big_real_mode(&insn_iret16); 7946055ea1fSAvi Kivity report("iret 2", 0, 1); 7957d36db35SAvi Kivity 79618253fdeSAvi Kivity exec_in_big_real_mode(&insn_iret_flags32); 7976055ea1fSAvi Kivity report("iret 3", R_AX, 1); 798964942e8SNadav Amit report("rflags.rf", ~0, !(outregs.eflags & (1 << 16))); 79918253fdeSAvi Kivity 80018253fdeSAvi Kivity exec_in_big_real_mode(&insn_iret_flags16); 8016055ea1fSAvi Kivity report("iret 4", R_AX, 1); 8027d36db35SAvi Kivity } 8037d36db35SAvi Kivity 8042e3f9f1fSThomas Huth static void test_int(void) 80596b9ca1eSMohammed Gamal { 806bd62e289SBill Wendling init_inregs(NULL); 80796b9ca1eSMohammed Gamal 80896b9ca1eSMohammed Gamal *(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */ 80996b9ca1eSMohammed Gamal *(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */ 81096b9ca1eSMohammed Gamal 81196b9ca1eSMohammed Gamal MK_INSN(int11, "int $0x11\n\t"); 81296b9ca1eSMohammed Gamal 81318253fdeSAvi Kivity exec_in_big_real_mode(&insn_int11); 8146055ea1fSAvi Kivity report("int 1", 0, 1); 81596b9ca1eSMohammed Gamal } 81696b9ca1eSMohammed Gamal 8178202cf84SRoman Bolshakov static void test_sti_inhibit(void) 8188202cf84SRoman Bolshakov { 8198202cf84SRoman Bolshakov init_inregs(NULL); 8208202cf84SRoman Bolshakov 8218202cf84SRoman Bolshakov *(u32 *)(0x73 * 4) = 0x1000; /* Store IRQ 11 handler in the IDT */ 8228202cf84SRoman Bolshakov *(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */ 8238202cf84SRoman Bolshakov 8248202cf84SRoman Bolshakov MK_INSN(sti_inhibit, "cli\n\t" 8258202cf84SRoman Bolshakov "movw $0x200b, %dx\n\t" 8268202cf84SRoman Bolshakov "movl $1, %eax\n\t" 8278202cf84SRoman Bolshakov "outl %eax, %dx\n\t" /* Set IRQ11 */ 8288202cf84SRoman Bolshakov "movl $0, %eax\n\t" 8298202cf84SRoman Bolshakov "outl %eax, %dx\n\t" /* Clear IRQ11 */ 8308202cf84SRoman Bolshakov "sti\n\t" 8318202cf84SRoman Bolshakov "hlt\n\t"); 8328202cf84SRoman Bolshakov exec_in_big_real_mode(&insn_sti_inhibit); 8338202cf84SRoman Bolshakov 8348202cf84SRoman Bolshakov report("sti inhibit", ~0, 1); 8358202cf84SRoman Bolshakov } 8368202cf84SRoman Bolshakov 8372e3f9f1fSThomas Huth static void test_imul(void) 838fa74f8a6SMohammed Gamal { 839fa74f8a6SMohammed Gamal MK_INSN(imul8_1, "mov $2, %al\n\t" 840fa74f8a6SMohammed Gamal "mov $-4, %cx\n\t" 841fa74f8a6SMohammed Gamal "imul %cl\n\t"); 842fa74f8a6SMohammed Gamal 843fa74f8a6SMohammed Gamal MK_INSN(imul16_1, "mov $2, %ax\n\t" 844fa74f8a6SMohammed Gamal "mov $-4, %cx\n\t" 845fa74f8a6SMohammed Gamal "imul %cx\n\t"); 846fa74f8a6SMohammed Gamal 847fa74f8a6SMohammed Gamal MK_INSN(imul32_1, "mov $2, %eax\n\t" 848fa74f8a6SMohammed Gamal "mov $-4, %ecx\n\t" 849fa74f8a6SMohammed Gamal "imul %ecx\n\t"); 850fa74f8a6SMohammed Gamal 851fa74f8a6SMohammed Gamal MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t" 852fa74f8a6SMohammed Gamal "mov $4, %cx\n\t" 853fa74f8a6SMohammed Gamal "imul %cl\n\t"); 854fa74f8a6SMohammed Gamal 855fa74f8a6SMohammed Gamal MK_INSN(imul16_2, "mov $2, %ax\n\t" 856fa74f8a6SMohammed Gamal "mov $4, %cx\n\t" 857fa74f8a6SMohammed Gamal "imul %cx\n\t"); 858fa74f8a6SMohammed Gamal 859fa74f8a6SMohammed Gamal MK_INSN(imul32_2, "mov $2, %eax\n\t" 860fa74f8a6SMohammed Gamal "mov $4, %ecx\n\t" 861fa74f8a6SMohammed Gamal "imul %ecx\n\t"); 862fa74f8a6SMohammed Gamal 863bd62e289SBill Wendling init_inregs(NULL); 86418253fdeSAvi Kivity 86518253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul8_1); 8666055ea1fSAvi Kivity report("imul 1", R_AX | R_CX | R_DX, (outregs.eax & 0xff) == (u8)-8); 867fa74f8a6SMohammed Gamal 86818253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul16_1); 8696055ea1fSAvi Kivity report("imul 2", R_AX | R_CX | R_DX, outregs.eax == (u16)-8); 870fa74f8a6SMohammed Gamal 87118253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul32_1); 8726055ea1fSAvi Kivity report("imul 3", R_AX | R_CX | R_DX, outregs.eax == (u32)-8); 873fa74f8a6SMohammed Gamal 87418253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul8_2); 8756055ea1fSAvi Kivity report("imul 4", R_AX | R_CX | R_DX, 8766055ea1fSAvi Kivity (outregs.eax & 0xffff) == 8 87781050840SAvi Kivity && (outregs.eax & 0xffff0000) == 0x12340000); 878fa74f8a6SMohammed Gamal 87918253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul16_2); 8806055ea1fSAvi Kivity report("imul 5", R_AX | R_CX | R_DX, outregs.eax == 8); 881fa74f8a6SMohammed Gamal 88218253fdeSAvi Kivity exec_in_big_real_mode(&insn_imul32_2); 8836055ea1fSAvi Kivity report("imul 6", R_AX | R_CX | R_DX, outregs.eax == 8); 884fa74f8a6SMohammed Gamal } 885fa74f8a6SMohammed Gamal 8862e3f9f1fSThomas Huth static void test_mul(void) 88759317bd1SMohammed Gamal { 88859317bd1SMohammed Gamal MK_INSN(mul8, "mov $2, %al\n\t" 88959317bd1SMohammed Gamal "mov $4, %cx\n\t" 89059317bd1SMohammed Gamal "imul %cl\n\t"); 89159317bd1SMohammed Gamal 89259317bd1SMohammed Gamal MK_INSN(mul16, "mov $2, %ax\n\t" 89359317bd1SMohammed Gamal "mov $4, %cx\n\t" 89459317bd1SMohammed Gamal "imul %cx\n\t"); 89559317bd1SMohammed Gamal 89659317bd1SMohammed Gamal MK_INSN(mul32, "mov $2, %eax\n\t" 89759317bd1SMohammed Gamal "mov $4, %ecx\n\t" 89859317bd1SMohammed Gamal "imul %ecx\n\t"); 89959317bd1SMohammed Gamal 900bd62e289SBill Wendling init_inregs(NULL); 90118253fdeSAvi Kivity 90218253fdeSAvi Kivity exec_in_big_real_mode(&insn_mul8); 9036055ea1fSAvi Kivity report("mul 1", R_AX | R_CX | R_DX, (outregs.eax & 0xff) == 8); 90459317bd1SMohammed Gamal 90518253fdeSAvi Kivity exec_in_big_real_mode(&insn_mul16); 9066055ea1fSAvi Kivity report("mul 2", R_AX | R_CX | R_DX, outregs.eax == 8); 90759317bd1SMohammed Gamal 90818253fdeSAvi Kivity exec_in_big_real_mode(&insn_mul32); 9096055ea1fSAvi Kivity report("mul 3", R_AX | R_CX | R_DX, outregs.eax == 8); 91059317bd1SMohammed Gamal } 91159317bd1SMohammed Gamal 9122e3f9f1fSThomas Huth static void test_div(void) 9130d4c7614SMohammed Gamal { 9140d4c7614SMohammed Gamal MK_INSN(div8, "mov $257, %ax\n\t" 9150d4c7614SMohammed Gamal "mov $2, %cl\n\t" 9160d4c7614SMohammed Gamal "div %cl\n\t"); 9170d4c7614SMohammed Gamal 9180d4c7614SMohammed Gamal MK_INSN(div16, "mov $512, %ax\n\t" 9190d4c7614SMohammed Gamal "mov $5, %cx\n\t" 9200d4c7614SMohammed Gamal "div %cx\n\t"); 9210d4c7614SMohammed Gamal 9220d4c7614SMohammed Gamal MK_INSN(div32, "mov $512, %eax\n\t" 9230d4c7614SMohammed Gamal "mov $5, %ecx\n\t" 9240d4c7614SMohammed Gamal "div %ecx\n\t"); 9250d4c7614SMohammed Gamal 926bd62e289SBill Wendling init_inregs(NULL); 92718253fdeSAvi Kivity 92818253fdeSAvi Kivity exec_in_big_real_mode(&insn_div8); 9296055ea1fSAvi Kivity report("div 1", R_AX | R_CX | R_DX, outregs.eax == 384); 9300d4c7614SMohammed Gamal 93118253fdeSAvi Kivity exec_in_big_real_mode(&insn_div16); 9326055ea1fSAvi Kivity report("div 2", R_AX | R_CX | R_DX, 9336055ea1fSAvi Kivity outregs.eax == 102 && outregs.edx == 2); 9340d4c7614SMohammed Gamal 93518253fdeSAvi Kivity exec_in_big_real_mode(&insn_div32); 9366055ea1fSAvi Kivity report("div 3", R_AX | R_CX | R_DX, 9376055ea1fSAvi Kivity outregs.eax == 102 && outregs.edx == 2); 9380d4c7614SMohammed Gamal } 9390d4c7614SMohammed Gamal 9402e3f9f1fSThomas Huth static void test_idiv(void) 9410d4c7614SMohammed Gamal { 9420d4c7614SMohammed Gamal MK_INSN(idiv8, "mov $256, %ax\n\t" 9430d4c7614SMohammed Gamal "mov $-2, %cl\n\t" 9440d4c7614SMohammed Gamal "idiv %cl\n\t"); 9450d4c7614SMohammed Gamal 9460d4c7614SMohammed Gamal MK_INSN(idiv16, "mov $512, %ax\n\t" 9470d4c7614SMohammed Gamal "mov $-2, %cx\n\t" 9480d4c7614SMohammed Gamal "idiv %cx\n\t"); 9490d4c7614SMohammed Gamal 9500d4c7614SMohammed Gamal MK_INSN(idiv32, "mov $512, %eax\n\t" 9510d4c7614SMohammed Gamal "mov $-2, %ecx\n\t" 9520d4c7614SMohammed Gamal "idiv %ecx\n\t"); 9530d4c7614SMohammed Gamal 954bd62e289SBill Wendling init_inregs(NULL); 95518253fdeSAvi Kivity 95618253fdeSAvi Kivity exec_in_big_real_mode(&insn_idiv8); 9576055ea1fSAvi Kivity report("idiv 1", R_AX | R_CX | R_DX, outregs.eax == (u8)-128); 9580d4c7614SMohammed Gamal 95918253fdeSAvi Kivity exec_in_big_real_mode(&insn_idiv16); 9606055ea1fSAvi Kivity report("idiv 2", R_AX | R_CX | R_DX, outregs.eax == (u16)-256); 9610d4c7614SMohammed Gamal 96218253fdeSAvi Kivity exec_in_big_real_mode(&insn_idiv32); 9636055ea1fSAvi Kivity report("idiv 3", R_AX | R_CX | R_DX, outregs.eax == (u32)-256); 9640d4c7614SMohammed Gamal } 9650d4c7614SMohammed Gamal 9662e3f9f1fSThomas Huth static void test_cbw(void) 9676e293cf5SWei Yongjun { 9686e293cf5SWei Yongjun MK_INSN(cbw, "mov $0xFE, %eax \n\t" 9696e293cf5SWei Yongjun "cbw\n\t"); 9706e293cf5SWei Yongjun MK_INSN(cwde, "mov $0xFFFE, %eax \n\t" 9716e293cf5SWei Yongjun "cwde\n\t"); 9726e293cf5SWei Yongjun 973bd62e289SBill Wendling init_inregs(NULL); 97418253fdeSAvi Kivity 97518253fdeSAvi Kivity exec_in_big_real_mode(&insn_cbw); 9766055ea1fSAvi Kivity report("cbq 1", ~0, outregs.eax == 0xFFFE); 9776e293cf5SWei Yongjun 97818253fdeSAvi Kivity exec_in_big_real_mode(&insn_cwde); 9796055ea1fSAvi Kivity report("cwde 1", ~0, outregs.eax == 0xFFFFFFFE); 9806e293cf5SWei Yongjun } 9816e293cf5SWei Yongjun 9822e3f9f1fSThomas Huth static void test_loopcc(void) 983eacef4e2SWei Yongjun { 984eacef4e2SWei Yongjun MK_INSN(loop, "mov $10, %ecx\n\t" 985eacef4e2SWei Yongjun "1: inc %eax\n\t" 986eacef4e2SWei Yongjun "loop 1b\n\t"); 987eacef4e2SWei Yongjun 988eacef4e2SWei Yongjun MK_INSN(loope, "mov $10, %ecx\n\t" 989eacef4e2SWei Yongjun "mov $1, %eax\n\t" 990eacef4e2SWei Yongjun "1: dec %eax\n\t" 991eacef4e2SWei Yongjun "loope 1b\n\t"); 992eacef4e2SWei Yongjun 993eacef4e2SWei Yongjun MK_INSN(loopne, "mov $10, %ecx\n\t" 994eacef4e2SWei Yongjun "mov $5, %eax\n\t" 995eacef4e2SWei Yongjun "1: dec %eax\n\t" 996eacef4e2SWei Yongjun "loopne 1b\n\t"); 997eacef4e2SWei Yongjun 998bd62e289SBill Wendling init_inregs(NULL); 999eacef4e2SWei Yongjun 100018253fdeSAvi Kivity exec_in_big_real_mode(&insn_loop); 10016055ea1fSAvi Kivity report("LOOPcc short 1", R_AX, outregs.eax == 10); 100218253fdeSAvi Kivity 100318253fdeSAvi Kivity exec_in_big_real_mode(&insn_loope); 10046055ea1fSAvi Kivity report("LOOPcc short 2", R_AX | R_CX, 10056055ea1fSAvi Kivity outregs.eax == -1 && outregs.ecx == 8); 1006eacef4e2SWei Yongjun 100718253fdeSAvi Kivity exec_in_big_real_mode(&insn_loopne); 10086055ea1fSAvi Kivity report("LOOPcc short 3", R_AX | R_CX, 10096055ea1fSAvi Kivity outregs.eax == 0 && outregs.ecx == 5); 1010eacef4e2SWei Yongjun } 1011eacef4e2SWei Yongjun 1012b274feedSAvi Kivity static void test_das(void) 1013b274feedSAvi Kivity { 1014b274feedSAvi Kivity short i; 101581050840SAvi Kivity u16 nr_fail = 0; 1016b274feedSAvi Kivity static unsigned test_cases[1024] = { 1017b274feedSAvi Kivity 0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00, 1018b274feedSAvi Kivity 0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01, 1019b274feedSAvi Kivity 0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02, 1020b274feedSAvi Kivity 0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03, 1021b274feedSAvi Kivity 0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04, 1022b274feedSAvi Kivity 0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05, 1023b274feedSAvi Kivity 0x06000606, 0x8701a606, 0x56100006, 0x9711a006, 1024b274feedSAvi Kivity 0x02000707, 0x8301a707, 0x12100107, 0x9311a107, 1025b274feedSAvi Kivity 0x02000808, 0x8301a808, 0x12100208, 0x9311a208, 1026b274feedSAvi Kivity 0x06000909, 0x8701a909, 0x16100309, 0x9711a309, 1027b274feedSAvi Kivity 0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a, 1028b274feedSAvi Kivity 0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b, 1029b274feedSAvi Kivity 0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c, 1030b274feedSAvi Kivity 0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d, 1031b274feedSAvi Kivity 0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e, 1032b274feedSAvi Kivity 0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f, 1033b274feedSAvi Kivity 0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10, 1034b274feedSAvi Kivity 0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11, 1035b274feedSAvi Kivity 0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12, 1036b274feedSAvi Kivity 0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13, 1037b274feedSAvi Kivity 0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14, 1038b274feedSAvi Kivity 0x02001515, 0x8301b515, 0x16100f15, 0x9711af15, 1039b274feedSAvi Kivity 0x02001616, 0x8301b616, 0x12101016, 0x9311b016, 1040b274feedSAvi Kivity 0x06001717, 0x8701b717, 0x16101117, 0x9711b117, 1041b274feedSAvi Kivity 0x06001818, 0x8701b818, 0x16101218, 0x9711b218, 1042b274feedSAvi Kivity 0x02001919, 0x8301b919, 0x12101319, 0x9311b319, 1043b274feedSAvi Kivity 0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a, 1044b274feedSAvi Kivity 0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b, 1045b274feedSAvi Kivity 0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c, 1046b274feedSAvi Kivity 0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d, 1047b274feedSAvi Kivity 0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e, 1048b274feedSAvi Kivity 0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f, 1049b274feedSAvi Kivity 0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20, 1050b274feedSAvi Kivity 0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21, 1051b274feedSAvi Kivity 0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22, 1052b274feedSAvi Kivity 0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23, 1053b274feedSAvi Kivity 0x06002424, 0x8301c424, 0x16101e24, 0x9711be24, 1054b274feedSAvi Kivity 0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25, 1055b274feedSAvi Kivity 0x02002626, 0x8701c626, 0x12102026, 0x9711c026, 1056b274feedSAvi Kivity 0x06002727, 0x8301c727, 0x16102127, 0x9311c127, 1057b274feedSAvi Kivity 0x06002828, 0x8301c828, 0x16102228, 0x9311c228, 1058b274feedSAvi Kivity 0x02002929, 0x8701c929, 0x12102329, 0x9711c329, 1059b274feedSAvi Kivity 0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a, 1060b274feedSAvi Kivity 0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b, 1061b274feedSAvi Kivity 0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c, 1062b274feedSAvi Kivity 0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d, 1063b274feedSAvi Kivity 0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e, 1064b274feedSAvi Kivity 0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f, 1065b274feedSAvi Kivity 0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30, 1066b274feedSAvi Kivity 0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31, 1067b274feedSAvi Kivity 0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32, 1068b274feedSAvi Kivity 0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33, 1069b274feedSAvi Kivity 0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34, 1070b274feedSAvi Kivity 0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35, 1071b274feedSAvi Kivity 0x06003636, 0x8301d636, 0x16103036, 0x9311d036, 1072b274feedSAvi Kivity 0x02003737, 0x8701d737, 0x12103137, 0x9711d137, 1073b274feedSAvi Kivity 0x02003838, 0x8701d838, 0x12103238, 0x9711d238, 1074b274feedSAvi Kivity 0x06003939, 0x8301d939, 0x16103339, 0x9311d339, 1075b274feedSAvi Kivity 0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a, 1076b274feedSAvi Kivity 0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b, 1077b274feedSAvi Kivity 0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c, 1078b274feedSAvi Kivity 0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d, 1079b274feedSAvi Kivity 0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e, 1080b274feedSAvi Kivity 0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f, 1081b274feedSAvi Kivity 0x02004040, 0x8301e040, 0x16103a40, 0x9311da40, 1082b274feedSAvi Kivity 0x06004141, 0x8701e141, 0x12103b41, 0x9711db41, 1083b274feedSAvi Kivity 0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42, 1084b274feedSAvi Kivity 0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43, 1085b274feedSAvi Kivity 0x06004444, 0x8701e444, 0x12103e44, 0x9711de44, 1086b274feedSAvi Kivity 0x02004545, 0x8301e545, 0x16103f45, 0x9311df45, 1087b274feedSAvi Kivity 0x02004646, 0x8301e646, 0x12104046, 0x9311e046, 1088b274feedSAvi Kivity 0x06004747, 0x8701e747, 0x16104147, 0x9711e147, 1089b274feedSAvi Kivity 0x06004848, 0x8701e848, 0x16104248, 0x9711e248, 1090b274feedSAvi Kivity 0x02004949, 0x8301e949, 0x12104349, 0x9311e349, 1091b274feedSAvi Kivity 0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a, 1092b274feedSAvi Kivity 0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b, 1093b274feedSAvi Kivity 0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c, 1094b274feedSAvi Kivity 0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d, 1095b274feedSAvi Kivity 0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e, 1096b274feedSAvi Kivity 0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f, 1097b274feedSAvi Kivity 0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50, 1098b274feedSAvi Kivity 0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51, 1099b274feedSAvi Kivity 0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52, 1100b274feedSAvi Kivity 0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53, 1101b274feedSAvi Kivity 0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54, 1102b274feedSAvi Kivity 0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55, 1103b274feedSAvi Kivity 0x06005656, 0x8701f656, 0x16105056, 0x9711f056, 1104b274feedSAvi Kivity 0x02005757, 0x8301f757, 0x12105157, 0x9311f157, 1105b274feedSAvi Kivity 0x02005858, 0x8301f858, 0x12105258, 0x9311f258, 1106b274feedSAvi Kivity 0x06005959, 0x8701f959, 0x16105359, 0x9711f359, 1107b274feedSAvi Kivity 0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a, 1108b274feedSAvi Kivity 0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b, 1109b274feedSAvi Kivity 0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c, 1110b274feedSAvi Kivity 0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d, 1111b274feedSAvi Kivity 0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e, 1112b274feedSAvi Kivity 0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f, 1113b274feedSAvi Kivity 0x06006060, 0x47010060, 0x16105a60, 0x9711fa60, 1114b274feedSAvi Kivity 0x02006161, 0x03010161, 0x12105b61, 0x9311fb61, 1115b274feedSAvi Kivity 0x02006262, 0x03010262, 0x16105c62, 0x9711fc62, 1116b274feedSAvi Kivity 0x06006363, 0x07010363, 0x12105d63, 0x9311fd63, 1117b274feedSAvi Kivity 0x02006464, 0x03010464, 0x12105e64, 0x9311fe64, 1118b274feedSAvi Kivity 0x06006565, 0x07010565, 0x16105f65, 0x9711ff65, 1119b274feedSAvi Kivity 0x06006666, 0x07010666, 0x16106066, 0x57110066, 1120b274feedSAvi Kivity 0x02006767, 0x03010767, 0x12106167, 0x13110167, 1121b274feedSAvi Kivity 0x02006868, 0x03010868, 0x12106268, 0x13110268, 1122b274feedSAvi Kivity 0x06006969, 0x07010969, 0x16106369, 0x17110369, 1123b274feedSAvi Kivity 0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a, 1124b274feedSAvi Kivity 0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b, 1125b274feedSAvi Kivity 0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c, 1126b274feedSAvi Kivity 0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d, 1127b274feedSAvi Kivity 0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e, 1128b274feedSAvi Kivity 0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f, 1129b274feedSAvi Kivity 0x02007070, 0x03011070, 0x16106a70, 0x17110a70, 1130b274feedSAvi Kivity 0x06007171, 0x07011171, 0x12106b71, 0x13110b71, 1131b274feedSAvi Kivity 0x06007272, 0x07011272, 0x16106c72, 0x17110c72, 1132b274feedSAvi Kivity 0x02007373, 0x03011373, 0x12106d73, 0x13110d73, 1133b274feedSAvi Kivity 0x06007474, 0x07011474, 0x12106e74, 0x13110e74, 1134b274feedSAvi Kivity 0x02007575, 0x03011575, 0x16106f75, 0x17110f75, 1135b274feedSAvi Kivity 0x02007676, 0x03011676, 0x12107076, 0x13111076, 1136b274feedSAvi Kivity 0x06007777, 0x07011777, 0x16107177, 0x17111177, 1137b274feedSAvi Kivity 0x06007878, 0x07011878, 0x16107278, 0x17111278, 1138b274feedSAvi Kivity 0x02007979, 0x03011979, 0x12107379, 0x13111379, 1139b274feedSAvi Kivity 0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a, 1140b274feedSAvi Kivity 0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b, 1141b274feedSAvi Kivity 0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c, 1142b274feedSAvi Kivity 0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d, 1143b274feedSAvi Kivity 0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e, 1144b274feedSAvi Kivity 0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f, 1145b274feedSAvi Kivity 0x82008080, 0x03012080, 0x12107a80, 0x13111a80, 1146b274feedSAvi Kivity 0x86008181, 0x07012181, 0x16107b81, 0x17111b81, 1147b274feedSAvi Kivity 0x86008282, 0x07012282, 0x12107c82, 0x13111c82, 1148b274feedSAvi Kivity 0x82008383, 0x03012383, 0x16107d83, 0x17111d83, 1149b274feedSAvi Kivity 0x86008484, 0x07012484, 0x16107e84, 0x17111e84, 1150b274feedSAvi Kivity 0x82008585, 0x03012585, 0x12107f85, 0x13111f85, 1151b274feedSAvi Kivity 0x82008686, 0x03012686, 0x92108086, 0x13112086, 1152b274feedSAvi Kivity 0x86008787, 0x07012787, 0x96108187, 0x17112187, 1153b274feedSAvi Kivity 0x86008888, 0x07012888, 0x96108288, 0x17112288, 1154b274feedSAvi Kivity 0x82008989, 0x03012989, 0x92108389, 0x13112389, 1155b274feedSAvi Kivity 0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a, 1156b274feedSAvi Kivity 0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b, 1157b274feedSAvi Kivity 0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c, 1158b274feedSAvi Kivity 0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d, 1159b274feedSAvi Kivity 0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e, 1160b274feedSAvi Kivity 0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f, 1161b274feedSAvi Kivity 0x86009090, 0x07013090, 0x92108a90, 0x13112a90, 1162b274feedSAvi Kivity 0x82009191, 0x03013191, 0x96108b91, 0x17112b91, 1163b274feedSAvi Kivity 0x82009292, 0x03013292, 0x92108c92, 0x13112c92, 1164b274feedSAvi Kivity 0x86009393, 0x07013393, 0x96108d93, 0x17112d93, 1165b274feedSAvi Kivity 0x82009494, 0x03013494, 0x96108e94, 0x17112e94, 1166b274feedSAvi Kivity 0x86009595, 0x07013595, 0x92108f95, 0x13112f95, 1167b274feedSAvi Kivity 0x86009696, 0x07013696, 0x96109096, 0x17113096, 1168b274feedSAvi Kivity 0x82009797, 0x03013797, 0x92109197, 0x13113197, 1169b274feedSAvi Kivity 0x82009898, 0x03013898, 0x92109298, 0x13113298, 1170b274feedSAvi Kivity 0x86009999, 0x07013999, 0x96109399, 0x17113399, 1171b274feedSAvi Kivity 0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a, 1172b274feedSAvi Kivity 0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b, 1173b274feedSAvi Kivity 0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c, 1174b274feedSAvi Kivity 0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d, 1175b274feedSAvi Kivity 0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e, 1176b274feedSAvi Kivity 0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f, 1177b274feedSAvi Kivity 0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0, 1178b274feedSAvi Kivity 0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1, 1179b274feedSAvi Kivity 0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2, 1180b274feedSAvi Kivity 0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3, 1181b274feedSAvi Kivity 0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4, 1182b274feedSAvi Kivity 0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5, 1183b274feedSAvi Kivity 0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6, 1184b274feedSAvi Kivity 0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7, 1185b274feedSAvi Kivity 0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8, 1186b274feedSAvi Kivity 0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9, 1187b274feedSAvi Kivity 0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa, 1188b274feedSAvi Kivity 0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab, 1189b274feedSAvi Kivity 0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac, 1190b274feedSAvi Kivity 0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad, 1191b274feedSAvi Kivity 0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae, 1192b274feedSAvi Kivity 0x130049af, 0x130149af, 0x131049af, 0x131149af, 1193b274feedSAvi Kivity 0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0, 1194b274feedSAvi Kivity 0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1, 1195b274feedSAvi Kivity 0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2, 1196b274feedSAvi Kivity 0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3, 1197b274feedSAvi Kivity 0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4, 1198b274feedSAvi Kivity 0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5, 1199b274feedSAvi Kivity 0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6, 1200b274feedSAvi Kivity 0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7, 1201b274feedSAvi Kivity 0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8, 1202b274feedSAvi Kivity 0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9, 1203b274feedSAvi Kivity 0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba, 1204b274feedSAvi Kivity 0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb, 1205b274feedSAvi Kivity 0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc, 1206b274feedSAvi Kivity 0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd, 1207b274feedSAvi Kivity 0x130058be, 0x130158be, 0x131058be, 0x131158be, 1208b274feedSAvi Kivity 0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf, 1209b274feedSAvi Kivity 0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0, 1210b274feedSAvi Kivity 0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1, 1211b274feedSAvi Kivity 0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2, 1212b274feedSAvi Kivity 0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3, 1213b274feedSAvi Kivity 0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4, 1214b274feedSAvi Kivity 0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5, 1215b274feedSAvi Kivity 0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6, 1216b274feedSAvi Kivity 0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7, 1217b274feedSAvi Kivity 0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8, 1218b274feedSAvi Kivity 0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9, 1219b274feedSAvi Kivity 0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca, 1220b274feedSAvi Kivity 0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb, 1221b274feedSAvi Kivity 0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc, 1222b274feedSAvi Kivity 0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd, 1223b274feedSAvi Kivity 0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce, 1224b274feedSAvi Kivity 0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf, 1225b274feedSAvi Kivity 0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0, 1226b274feedSAvi Kivity 0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1, 1227b274feedSAvi Kivity 0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2, 1228b274feedSAvi Kivity 0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3, 1229b274feedSAvi Kivity 0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4, 1230b274feedSAvi Kivity 0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5, 1231b274feedSAvi Kivity 0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6, 1232b274feedSAvi Kivity 0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7, 1233b274feedSAvi Kivity 0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8, 1234b274feedSAvi Kivity 0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9, 1235b274feedSAvi Kivity 0x170074da, 0x170174da, 0x171074da, 0x171174da, 1236b274feedSAvi Kivity 0x130075db, 0x130175db, 0x131075db, 0x131175db, 1237b274feedSAvi Kivity 0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc, 1238b274feedSAvi Kivity 0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd, 1239b274feedSAvi Kivity 0x170078de, 0x170178de, 0x171078de, 0x171178de, 1240b274feedSAvi Kivity 0x130079df, 0x130179df, 0x131079df, 0x131179df, 1241b274feedSAvi Kivity 0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0, 1242b274feedSAvi Kivity 0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1, 1243b274feedSAvi Kivity 0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2, 1244b274feedSAvi Kivity 0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3, 1245b274feedSAvi Kivity 0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4, 1246b274feedSAvi Kivity 0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5, 1247b274feedSAvi Kivity 0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6, 1248b274feedSAvi Kivity 0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7, 1249b274feedSAvi Kivity 0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8, 1250b274feedSAvi Kivity 0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9, 1251b274feedSAvi Kivity 0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea, 1252b274feedSAvi Kivity 0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb, 1253b274feedSAvi Kivity 0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec, 1254b274feedSAvi Kivity 0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed, 1255b274feedSAvi Kivity 0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee, 1256b274feedSAvi Kivity 0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef, 1257b274feedSAvi Kivity 0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0, 1258b274feedSAvi Kivity 0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1, 1259b274feedSAvi Kivity 0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2, 1260b274feedSAvi Kivity 0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3, 1261b274feedSAvi Kivity 0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4, 1262b274feedSAvi Kivity 0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5, 1263b274feedSAvi Kivity 0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6, 1264b274feedSAvi Kivity 0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7, 1265b274feedSAvi Kivity 0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8, 1266b274feedSAvi Kivity 0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9, 1267b274feedSAvi Kivity 0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa, 1268b274feedSAvi Kivity 0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb, 1269b274feedSAvi Kivity 0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc, 1270b274feedSAvi Kivity 0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd, 1271b274feedSAvi Kivity 0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe, 1272b274feedSAvi Kivity 0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff, 1273b274feedSAvi Kivity }; 1274b274feedSAvi Kivity 1275b274feedSAvi Kivity MK_INSN(das, "das"); 1276b274feedSAvi Kivity 1277bd62e289SBill Wendling init_inregs(NULL); 127818253fdeSAvi Kivity 1279b274feedSAvi Kivity for (i = 0; i < 1024; ++i) { 1280b274feedSAvi Kivity unsigned tmp = test_cases[i]; 1281b274feedSAvi Kivity inregs.eax = tmp & 0xff; 1282b274feedSAvi Kivity inregs.eflags = (tmp >> 16) & 0xff; 128318253fdeSAvi Kivity exec_in_big_real_mode(&insn_das); 128418253fdeSAvi Kivity if (!regs_equal(R_AX) 1285b274feedSAvi Kivity || outregs.eax != ((tmp >> 8) & 0xff) 1286b274feedSAvi Kivity || (outregs.eflags & 0xff) != (tmp >> 24)) { 128781050840SAvi Kivity ++nr_fail; 128881050840SAvi Kivity break; 1289b274feedSAvi Kivity } 1290b274feedSAvi Kivity } 12916055ea1fSAvi Kivity report("DAS", ~0, nr_fail == 0); 1292b274feedSAvi Kivity } 1293b274feedSAvi Kivity 12942e3f9f1fSThomas Huth static void test_cwd_cdq(void) 12950cbd5b06SMohammed Gamal { 12960cbd5b06SMohammed Gamal /* Sign-bit set */ 12970cbd5b06SMohammed Gamal MK_INSN(cwd_1, "mov $0x8000, %ax\n\t" 12980cbd5b06SMohammed Gamal "cwd\n\t"); 12990cbd5b06SMohammed Gamal 13000cbd5b06SMohammed Gamal /* Sign-bit not set */ 13010cbd5b06SMohammed Gamal MK_INSN(cwd_2, "mov $0x1000, %ax\n\t" 13020cbd5b06SMohammed Gamal "cwd\n\t"); 13030cbd5b06SMohammed Gamal 13040cbd5b06SMohammed Gamal /* Sign-bit set */ 13050cbd5b06SMohammed Gamal MK_INSN(cdq_1, "mov $0x80000000, %eax\n\t" 13060cbd5b06SMohammed Gamal "cdq\n\t"); 13070cbd5b06SMohammed Gamal 13080cbd5b06SMohammed Gamal /* Sign-bit not set */ 13090cbd5b06SMohammed Gamal MK_INSN(cdq_2, "mov $0x10000000, %eax\n\t" 13100cbd5b06SMohammed Gamal "cdq\n\t"); 13110cbd5b06SMohammed Gamal 1312bd62e289SBill Wendling init_inregs(NULL); 131318253fdeSAvi Kivity 131418253fdeSAvi Kivity exec_in_big_real_mode(&insn_cwd_1); 13156055ea1fSAvi Kivity report("cwd 1", R_AX | R_DX, 13166055ea1fSAvi Kivity outregs.eax == 0x8000 && outregs.edx == 0xffff); 13170cbd5b06SMohammed Gamal 131818253fdeSAvi Kivity exec_in_big_real_mode(&insn_cwd_2); 13196055ea1fSAvi Kivity report("cwd 2", R_AX | R_DX, 13206055ea1fSAvi Kivity outregs.eax == 0x1000 && outregs.edx == 0); 13210cbd5b06SMohammed Gamal 132218253fdeSAvi Kivity exec_in_big_real_mode(&insn_cdq_1); 13236055ea1fSAvi Kivity report("cdq 1", R_AX | R_DX, 13246055ea1fSAvi Kivity outregs.eax == 0x80000000 && outregs.edx == 0xffffffff); 13250cbd5b06SMohammed Gamal 132618253fdeSAvi Kivity exec_in_big_real_mode(&insn_cdq_2); 13276055ea1fSAvi Kivity report("cdq 2", R_AX | R_DX, 13286055ea1fSAvi Kivity outregs.eax == 0x10000000 && outregs.edx == 0); 13290cbd5b06SMohammed Gamal } 13300cbd5b06SMohammed Gamal 133137f51a4aSWei Yongjun static struct { 133237f51a4aSWei Yongjun void *address; 133337f51a4aSWei Yongjun unsigned short sel; 133437f51a4aSWei Yongjun } __attribute__((packed)) desc = { 133537f51a4aSWei Yongjun (void *)0x1234, 133637f51a4aSWei Yongjun 0x10, 133737f51a4aSWei Yongjun }; 133837f51a4aSWei Yongjun 13392e3f9f1fSThomas Huth static void test_lds_lss(void) 134037f51a4aSWei Yongjun { 1341bd62e289SBill Wendling init_inregs(&(struct regs){ .ebx = (unsigned long)&desc }); 134237f51a4aSWei Yongjun 1343*231b4c3bSRoman Bolshakov MK_INSN(lds, "pushl %ds\n\t" 134437f51a4aSWei Yongjun "lds (%ebx), %eax\n\t" 134537f51a4aSWei Yongjun "mov %ds, %ebx\n\t" 1346*231b4c3bSRoman Bolshakov "popl %ds\n\t"); 134737f51a4aSWei Yongjun exec_in_big_real_mode(&insn_lds); 134837f51a4aSWei Yongjun report("lds", R_AX | R_BX, 134937f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 135037f51a4aSWei Yongjun outregs.ebx == desc.sel); 135137f51a4aSWei Yongjun 1352eb6687a2SBill Wendling MK_INSN(les, "les (%ebx), %eax\n\t" 1353eb6687a2SBill Wendling "mov %es, %ebx\n\t"); 135437f51a4aSWei Yongjun exec_in_big_real_mode(&insn_les); 135537f51a4aSWei Yongjun report("les", R_AX | R_BX, 135637f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 135737f51a4aSWei Yongjun outregs.ebx == desc.sel); 135837f51a4aSWei Yongjun 1359*231b4c3bSRoman Bolshakov MK_INSN(lfs, "pushl %fs\n\t" 136037f51a4aSWei Yongjun "lfs (%ebx), %eax\n\t" 136137f51a4aSWei Yongjun "mov %fs, %ebx\n\t" 1362*231b4c3bSRoman Bolshakov "popl %fs\n\t"); 136337f51a4aSWei Yongjun exec_in_big_real_mode(&insn_lfs); 136437f51a4aSWei Yongjun report("lfs", R_AX | R_BX, 136537f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 136637f51a4aSWei Yongjun outregs.ebx == desc.sel); 136737f51a4aSWei Yongjun 1368*231b4c3bSRoman Bolshakov MK_INSN(lgs, "pushl %gs\n\t" 136937f51a4aSWei Yongjun "lgs (%ebx), %eax\n\t" 137037f51a4aSWei Yongjun "mov %gs, %ebx\n\t" 1371*231b4c3bSRoman Bolshakov "popl %gs\n\t"); 137237f51a4aSWei Yongjun exec_in_big_real_mode(&insn_lgs); 137337f51a4aSWei Yongjun report("lgs", R_AX | R_BX, 137437f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 137537f51a4aSWei Yongjun outregs.ebx == desc.sel); 137637f51a4aSWei Yongjun 1377*231b4c3bSRoman Bolshakov MK_INSN(lss, "pushl %ss\n\t" 137837f51a4aSWei Yongjun "lss (%ebx), %eax\n\t" 137937f51a4aSWei Yongjun "mov %ss, %ebx\n\t" 1380*231b4c3bSRoman Bolshakov "popl %ss\n\t"); 138137f51a4aSWei Yongjun exec_in_big_real_mode(&insn_lss); 138237f51a4aSWei Yongjun report("lss", R_AX | R_BX, 138337f51a4aSWei Yongjun outregs.eax == (unsigned long)desc.address && 138437f51a4aSWei Yongjun outregs.ebx == desc.sel); 138537f51a4aSWei Yongjun } 138637f51a4aSWei Yongjun 13872e3f9f1fSThomas Huth static void test_jcxz(void) 1388b1c7c575SWei Yongjun { 1389b1c7c575SWei Yongjun MK_INSN(jcxz1, "jcxz 1f\n\t" 1390b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1391b1c7c575SWei Yongjun "1:\n\t"); 1392b1c7c575SWei Yongjun MK_INSN(jcxz2, "mov $0x100, %ecx\n\t" 1393b1c7c575SWei Yongjun "jcxz 1f\n\t" 1394b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1395b1c7c575SWei Yongjun "mov $0, %ecx\n\t" 1396b1c7c575SWei Yongjun "1:\n\t"); 1397b1c7c575SWei Yongjun MK_INSN(jcxz3, "mov $0x10000, %ecx\n\t" 1398b1c7c575SWei Yongjun "jcxz 1f\n\t" 1399b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1400b1c7c575SWei Yongjun "1:\n\t"); 1401b1c7c575SWei Yongjun MK_INSN(jecxz1, "jecxz 1f\n\t" 1402b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1403b1c7c575SWei Yongjun "1:\n\t"); 1404b1c7c575SWei Yongjun MK_INSN(jecxz2, "mov $0x10000, %ecx\n\t" 1405b1c7c575SWei Yongjun "jecxz 1f\n\t" 1406b1c7c575SWei Yongjun "mov $0x1234, %eax\n\t" 1407b1c7c575SWei Yongjun "mov $0, %ecx\n\t" 1408b1c7c575SWei Yongjun "1:\n\t"); 1409b1c7c575SWei Yongjun 1410bd62e289SBill Wendling init_inregs(NULL); 1411b1c7c575SWei Yongjun 1412b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jcxz1); 1413b1c7c575SWei Yongjun report("jcxz short 1", 0, 1); 1414b1c7c575SWei Yongjun 1415b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jcxz2); 1416b1c7c575SWei Yongjun report("jcxz short 2", R_AX, outregs.eax == 0x1234); 1417b1c7c575SWei Yongjun 1418b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jcxz3); 1419b1c7c575SWei Yongjun report("jcxz short 3", R_CX, outregs.ecx == 0x10000); 1420b1c7c575SWei Yongjun 1421b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jecxz1); 1422b1c7c575SWei Yongjun report("jecxz short 1", 0, 1); 1423b1c7c575SWei Yongjun 1424b1c7c575SWei Yongjun exec_in_big_real_mode(&insn_jecxz2); 1425b1c7c575SWei Yongjun report("jecxz short 2", R_AX, outregs.eax == 0x1234); 1426b1c7c575SWei Yongjun } 1427b1c7c575SWei Yongjun 14288f578e98SAvi Kivity static void test_cpuid(void) 14298f578e98SAvi Kivity { 14308f578e98SAvi Kivity MK_INSN(cpuid, "cpuid"); 14318f578e98SAvi Kivity unsigned function = 0x1234; 14328f578e98SAvi Kivity unsigned eax, ebx, ecx, edx; 14338f578e98SAvi Kivity 1434bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = function }); 1435bd62e289SBill Wendling 1436bd62e289SBill Wendling eax = inregs.eax; 1437bd62e289SBill Wendling ecx = inregs.ecx; 1438674d2dbeSPaolo Bonzini asm("cpuid" : "+a"(eax), "=b"(ebx), "+c"(ecx), "=d"(edx)); 14398f578e98SAvi Kivity exec_in_big_real_mode(&insn_cpuid); 14408f578e98SAvi Kivity report("cpuid", R_AX|R_BX|R_CX|R_DX, 14418f578e98SAvi Kivity outregs.eax == eax && outregs.ebx == ebx 14428f578e98SAvi Kivity && outregs.ecx == ecx && outregs.edx == edx); 14438f578e98SAvi Kivity } 14448f578e98SAvi Kivity 1445ed93f43bSAvi Kivity static void test_ss_base_for_esp_ebp(void) 1446ed93f43bSAvi Kivity { 1447ed93f43bSAvi Kivity MK_INSN(ssrel1, "mov %ss, %ax; mov %bx, %ss; movl (%ebp), %ebx; mov %ax, %ss"); 1448ed93f43bSAvi Kivity MK_INSN(ssrel2, "mov %ss, %ax; mov %bx, %ss; movl (%ebp,%edi,8), %ebx; mov %ax, %ss"); 1449ed93f43bSAvi Kivity static unsigned array[] = { 0x12345678, 0, 0, 0, 0x87654321 }; 1450ed93f43bSAvi Kivity 1451bd62e289SBill Wendling init_inregs(&(struct regs){ .ebx = 1, .ebp = (unsigned)array }); 1452bd62e289SBill Wendling 1453ed93f43bSAvi Kivity exec_in_big_real_mode(&insn_ssrel1); 1454ed93f43bSAvi Kivity report("ss relative addressing (1)", R_AX | R_BX, outregs.ebx == 0x87654321); 1455bd62e289SBill Wendling 1456ed93f43bSAvi Kivity inregs.ebx = 1; 1457ed93f43bSAvi Kivity inregs.ebp = (unsigned)array; 1458ed93f43bSAvi Kivity inregs.edi = 0; 1459ed93f43bSAvi Kivity exec_in_big_real_mode(&insn_ssrel2); 1460ed93f43bSAvi Kivity report("ss relative addressing (2)", R_AX | R_BX, outregs.ebx == 0x87654321); 1461ed93f43bSAvi Kivity } 1462ed93f43bSAvi Kivity 1463975ca087SPeter Feiner extern unsigned long long r_gdt[]; 1464975ca087SPeter Feiner 1465c2281fa4SAvi Kivity static void test_sgdt_sidt(void) 1466c2281fa4SAvi Kivity { 1467c2281fa4SAvi Kivity MK_INSN(sgdt, "sgdtw (%eax)"); 1468c2281fa4SAvi Kivity MK_INSN(sidt, "sidtw (%eax)"); 1469975ca087SPeter Feiner struct table_descr x, y; 1470c2281fa4SAvi Kivity 1471bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = (unsigned)&y }); 1472bd62e289SBill Wendling 1473c2281fa4SAvi Kivity asm volatile("sgdtw %0" : "=m"(x)); 1474c2281fa4SAvi Kivity exec_in_big_real_mode(&insn_sgdt); 1475975ca087SPeter Feiner report("sgdt", 0, x.limit == y.limit && x.base == y.base); 1476c2281fa4SAvi Kivity 1477c2281fa4SAvi Kivity inregs.eax = (unsigned)&y; 1478c2281fa4SAvi Kivity asm volatile("sidtw %0" : "=m"(x)); 1479c2281fa4SAvi Kivity exec_in_big_real_mode(&insn_sidt); 1480975ca087SPeter Feiner report("sidt", 0, x.limit == y.limit && x.base == y.base); 1481c2281fa4SAvi Kivity } 1482c2281fa4SAvi Kivity 148388b6dac4SPaolo Bonzini static void test_sahf(void) 148488b6dac4SPaolo Bonzini { 148588b6dac4SPaolo Bonzini MK_INSN(sahf, "sahf; pushfw; mov (%esp), %al; popfw"); 148688b6dac4SPaolo Bonzini 1487bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0xfd00 }); 1488bd62e289SBill Wendling 148988b6dac4SPaolo Bonzini exec_in_big_real_mode(&insn_sahf); 149088b6dac4SPaolo Bonzini report("sahf", R_AX, outregs.eax == (inregs.eax | 0xd7)); 149188b6dac4SPaolo Bonzini } 149288b6dac4SPaolo Bonzini 14937ae3645aSAvi Kivity static void test_lahf(void) 14947ae3645aSAvi Kivity { 14957ae3645aSAvi Kivity MK_INSN(lahf, "pushfw; mov %al, (%esp); popfw; lahf"); 14967ae3645aSAvi Kivity 1497bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0xc7 }); 1498bd62e289SBill Wendling 14997ae3645aSAvi Kivity exec_in_big_real_mode(&insn_lahf); 15007ae3645aSAvi Kivity report("lahf", R_AX, (outregs.eax >> 8) == inregs.eax); 15017ae3645aSAvi Kivity } 15027ae3645aSAvi Kivity 1503fd9ea640SAvi Kivity static void test_movzx_movsx(void) 1504fd9ea640SAvi Kivity { 1505fd9ea640SAvi Kivity MK_INSN(movsx, "movsx %al, %ebx"); 1506fd9ea640SAvi Kivity MK_INSN(movzx, "movzx %al, %ebx"); 15073013e079SGleb Natapov MK_INSN(movzsah, "movsx %ah, %ebx"); 15083013e079SGleb Natapov MK_INSN(movzxah, "movzx %ah, %ebx"); 1509fd9ea640SAvi Kivity 1510bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x1234569c }); 1511bd62e289SBill Wendling 1512fd9ea640SAvi Kivity exec_in_big_real_mode(&insn_movsx); 1513fd9ea640SAvi Kivity report("movsx", R_BX, outregs.ebx == (signed char)inregs.eax); 1514fd9ea640SAvi Kivity exec_in_big_real_mode(&insn_movzx); 1515fd9ea640SAvi Kivity report("movzx", R_BX, outregs.ebx == (unsigned char)inregs.eax); 15163013e079SGleb Natapov exec_in_big_real_mode(&insn_movzsah); 15173013e079SGleb Natapov report("movsx ah", R_BX, outregs.ebx == (signed char)(inregs.eax>>8)); 15183013e079SGleb Natapov exec_in_big_real_mode(&insn_movzxah); 15193013e079SGleb Natapov report("movzx ah", R_BX, outregs.ebx == (unsigned char)(inregs.eax >> 8)); 1520fd9ea640SAvi Kivity } 1521fd9ea640SAvi Kivity 1522b493b2e8SAvi Kivity static void test_bswap(void) 1523b493b2e8SAvi Kivity { 1524b493b2e8SAvi Kivity MK_INSN(bswap, "bswap %ecx"); 1525b493b2e8SAvi Kivity 1526bd62e289SBill Wendling init_inregs(&(struct regs){ .ecx = 0x12345678 }); 1527bd62e289SBill Wendling 1528b493b2e8SAvi Kivity exec_in_big_real_mode(&insn_bswap); 1529b493b2e8SAvi Kivity report("bswap", R_CX, outregs.ecx == 0x78563412); 1530b493b2e8SAvi Kivity } 1531b493b2e8SAvi Kivity 15328cd86387SGleb Natapov static void test_aad(void) 15338cd86387SGleb Natapov { 15348cd86387SGleb Natapov MK_INSN(aad, "aad"); 15358cd86387SGleb Natapov 1536bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x12345678 }); 1537bd62e289SBill Wendling 15388cd86387SGleb Natapov exec_in_big_real_mode(&insn_aad); 15398cd86387SGleb Natapov report("aad", R_AX, outregs.eax == 0x123400d4); 15408cd86387SGleb Natapov } 15418cd86387SGleb Natapov 15422a9b5718SPaolo Bonzini static void test_aam(void) 15432a9b5718SPaolo Bonzini { 15442a9b5718SPaolo Bonzini MK_INSN(aam, "aam"); 15452a9b5718SPaolo Bonzini 1546bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x76543210 }); 1547bd62e289SBill Wendling 15482a9b5718SPaolo Bonzini exec_in_big_real_mode(&insn_aam); 15492a9b5718SPaolo Bonzini report("aam", R_AX, outregs.eax == 0x76540106); 15502a9b5718SPaolo Bonzini } 15512a9b5718SPaolo Bonzini 15522a9b5718SPaolo Bonzini static void test_xlat(void) 15532a9b5718SPaolo Bonzini { 15542a9b5718SPaolo Bonzini MK_INSN(xlat, "xlat"); 15552a9b5718SPaolo Bonzini u8 table[256]; 15562a9b5718SPaolo Bonzini int i; 15572a9b5718SPaolo Bonzini 15582a9b5718SPaolo Bonzini for (i = 0; i < 256; i++) { 15592a9b5718SPaolo Bonzini table[i] = i + 1; 15602a9b5718SPaolo Bonzini } 15612a9b5718SPaolo Bonzini 1562bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x89abcdef, .ebx = (u32)table }); 1563bd62e289SBill Wendling 15642a9b5718SPaolo Bonzini exec_in_big_real_mode(&insn_xlat); 15652a9b5718SPaolo Bonzini report("xlat", R_AX, outregs.eax == 0x89abcdf0); 15662a9b5718SPaolo Bonzini } 15672a9b5718SPaolo Bonzini 15682a9b5718SPaolo Bonzini static void test_salc(void) 15692a9b5718SPaolo Bonzini { 15702a9b5718SPaolo Bonzini MK_INSN(clc_salc, "clc; .byte 0xd6"); 15712a9b5718SPaolo Bonzini MK_INSN(stc_salc, "stc; .byte 0xd6"); 15722a9b5718SPaolo Bonzini 1573bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x12345678 }); 1574bd62e289SBill Wendling 15752a9b5718SPaolo Bonzini exec_in_big_real_mode(&insn_clc_salc); 15762a9b5718SPaolo Bonzini report("salc (1)", R_AX, outregs.eax == 0x12345600); 15772a9b5718SPaolo Bonzini exec_in_big_real_mode(&insn_stc_salc); 15782a9b5718SPaolo Bonzini report("salc (2)", R_AX, outregs.eax == 0x123456ff); 15792a9b5718SPaolo Bonzini } 15802a9b5718SPaolo Bonzini 15810987db7aSGleb Natapov static void test_fninit(void) 15820987db7aSGleb Natapov { 15830987db7aSGleb Natapov u16 fcw = -1, fsw = -1; 15840987db7aSGleb Natapov MK_INSN(fninit, "fninit ; fnstsw (%eax) ; fnstcw (%ebx)"); 15850987db7aSGleb Natapov 1586bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = (u32)&fsw, .ebx = (u32)&fcw }); 15870987db7aSGleb Natapov 15880987db7aSGleb Natapov exec_in_big_real_mode(&insn_fninit); 15890987db7aSGleb Natapov report("fninit", 0, fsw == 0 && (fcw & 0x103f) == 0x003f); 15900987db7aSGleb Natapov } 15910987db7aSGleb Natapov 15921a4c03a0SArthur Chunqi Li static void test_nopl(void) 15931a4c03a0SArthur Chunqi Li { 15941a4c03a0SArthur Chunqi Li MK_INSN(nopl1, ".byte 0x90\n\r"); // 1 byte nop 15951a4c03a0SArthur Chunqi Li MK_INSN(nopl2, ".byte 0x66, 0x90\n\r"); // 2 bytes nop 15961a4c03a0SArthur Chunqi Li MK_INSN(nopl3, ".byte 0x0f, 0x1f, 0x00\n\r"); // 3 bytes nop 15971a4c03a0SArthur Chunqi Li MK_INSN(nopl4, ".byte 0x0f, 0x1f, 0x40, 0x00\n\r"); // 4 bytes nop 15981a4c03a0SArthur Chunqi Li exec_in_big_real_mode(&insn_nopl1); 15991a4c03a0SArthur Chunqi Li exec_in_big_real_mode(&insn_nopl2); 16001a4c03a0SArthur Chunqi Li exec_in_big_real_mode(&insn_nopl3); 16011a4c03a0SArthur Chunqi Li exec_in_big_real_mode(&insn_nopl4); 16021a4c03a0SArthur Chunqi Li report("nopl", 0, 1); 16031a4c03a0SArthur Chunqi Li } 16041a4c03a0SArthur Chunqi Li 1605b5105e8bSPaolo Bonzini static u32 perf_baseline; 1606b5105e8bSPaolo Bonzini 16077505ea23SPaolo Bonzini #define PERF_COUNT 1000000 1608b5105e8bSPaolo Bonzini 1609b5105e8bSPaolo Bonzini #define MK_INSN_PERF(name, insn) \ 1610b5105e8bSPaolo Bonzini MK_INSN(name, "rdtsc; mov %eax, %ebx; mov %edx, %esi\n" \ 1611b5105e8bSPaolo Bonzini "1:" insn "\n" \ 16127505ea23SPaolo Bonzini ".byte 0x67; loop 1b\n" \ 1613b5105e8bSPaolo Bonzini "rdtsc"); 1614b5105e8bSPaolo Bonzini 1615b5105e8bSPaolo Bonzini static u32 cycles_in_big_real_mode(struct insn_desc *insn) 1616b5105e8bSPaolo Bonzini { 1617b5105e8bSPaolo Bonzini u64 start, end; 1618b5105e8bSPaolo Bonzini 1619bd62e289SBill Wendling init_inregs(&(struct regs){ .ecx = PERF_COUNT }); 1620bd62e289SBill Wendling 1621b5105e8bSPaolo Bonzini exec_in_big_real_mode(insn); 1622b5105e8bSPaolo Bonzini start = ((u64)outregs.esi << 32) | outregs.ebx; 1623b5105e8bSPaolo Bonzini end = ((u64)outregs.edx << 32) | outregs.eax; 1624b5105e8bSPaolo Bonzini 1625b5105e8bSPaolo Bonzini return end - start; 1626b5105e8bSPaolo Bonzini } 1627b5105e8bSPaolo Bonzini 1628b5105e8bSPaolo Bonzini static void test_perf_loop(void) 1629b5105e8bSPaolo Bonzini { 1630b5105e8bSPaolo Bonzini /* 1631b5105e8bSPaolo Bonzini * This test runs simple instructions that should roughly take the 1632b5105e8bSPaolo Bonzini * the same time to emulate: PERF_COUNT iterations of "loop" and 3 1633b5105e8bSPaolo Bonzini * setup instructions. Other performance tests can run PERF_COUNT 1634b5105e8bSPaolo Bonzini * iterations of the same instruction and subtract the cycle count 1635b5105e8bSPaolo Bonzini * of this test. 1636b5105e8bSPaolo Bonzini */ 1637b5105e8bSPaolo Bonzini MK_INSN_PERF(perf_loop, ""); 1638b5105e8bSPaolo Bonzini perf_baseline = cycles_in_big_real_mode(&insn_perf_loop); 1639b5105e8bSPaolo Bonzini print_serial_u32(perf_baseline / (PERF_COUNT + 3)); 1640b5105e8bSPaolo Bonzini print_serial(" cycles/emulated jump instruction\n"); 1641b5105e8bSPaolo Bonzini } 1642b5105e8bSPaolo Bonzini 1643b5105e8bSPaolo Bonzini static void test_perf_mov(void) 1644b5105e8bSPaolo Bonzini { 1645b5105e8bSPaolo Bonzini u32 cyc; 1646b5105e8bSPaolo Bonzini 1647b5105e8bSPaolo Bonzini MK_INSN_PERF(perf_move, "mov %esi, %edi"); 1648b5105e8bSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_move); 1649b5105e8bSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 1650b5105e8bSPaolo Bonzini print_serial(" cycles/emulated move instruction\n"); 1651b5105e8bSPaolo Bonzini } 1652b5105e8bSPaolo Bonzini 1653b5105e8bSPaolo Bonzini static void test_perf_arith(void) 1654b5105e8bSPaolo Bonzini { 1655b5105e8bSPaolo Bonzini u32 cyc; 1656b5105e8bSPaolo Bonzini 1657b5105e8bSPaolo Bonzini MK_INSN_PERF(perf_arith, "add $4, %edi"); 1658b5105e8bSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_arith); 1659b5105e8bSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 1660b5105e8bSPaolo Bonzini print_serial(" cycles/emulated arithmetic instruction\n"); 1661b5105e8bSPaolo Bonzini } 1662b5105e8bSPaolo Bonzini 1663b5105e8bSPaolo Bonzini static void test_perf_memory_load(void) 1664b5105e8bSPaolo Bonzini { 1665b5105e8bSPaolo Bonzini u32 cyc, tmp; 1666b5105e8bSPaolo Bonzini 1667576718d0SBill Wendling MK_INSN_PERF(perf_memory_load, "cmpw $0, (%edi)"); 1668bd62e289SBill Wendling 1669bd62e289SBill Wendling init_inregs(&(struct regs){ .edi = (u32)&tmp }); 1670bd62e289SBill Wendling 1671b5105e8bSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_memory_load); 1672b5105e8bSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 1673b5105e8bSPaolo Bonzini print_serial(" cycles/emulated memory load instruction\n"); 1674b5105e8bSPaolo Bonzini } 1675b5105e8bSPaolo Bonzini 16769306cb8eSPaolo Bonzini static void test_perf_memory_store(void) 16779306cb8eSPaolo Bonzini { 16789306cb8eSPaolo Bonzini u32 cyc, tmp; 16799306cb8eSPaolo Bonzini 1680576718d0SBill Wendling MK_INSN_PERF(perf_memory_store, "movw %ax, (%edi)"); 1681bd62e289SBill Wendling 1682bd62e289SBill Wendling init_inregs(&(struct regs){ .edi = (u32)&tmp }); 1683bd62e289SBill Wendling 16849306cb8eSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_memory_store); 16859306cb8eSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 16869306cb8eSPaolo Bonzini print_serial(" cycles/emulated memory store instruction\n"); 16879306cb8eSPaolo Bonzini } 16889306cb8eSPaolo Bonzini 1689b5105e8bSPaolo Bonzini static void test_perf_memory_rmw(void) 1690b5105e8bSPaolo Bonzini { 1691b5105e8bSPaolo Bonzini u32 cyc, tmp; 1692b5105e8bSPaolo Bonzini 1693576718d0SBill Wendling MK_INSN_PERF(perf_memory_rmw, "addw $1, (%edi)"); 1694bd62e289SBill Wendling 1695bd62e289SBill Wendling init_inregs(&(struct regs){ .edi = (u32)&tmp }); 1696bd62e289SBill Wendling 1697b5105e8bSPaolo Bonzini cyc = cycles_in_big_real_mode(&insn_perf_memory_rmw); 1698b5105e8bSPaolo Bonzini print_serial_u32((cyc - perf_baseline) / PERF_COUNT); 1699b5105e8bSPaolo Bonzini print_serial(" cycles/emulated memory RMW instruction\n"); 1700b5105e8bSPaolo Bonzini } 1701b5105e8bSPaolo Bonzini 17022e3f9f1fSThomas Huth static void test_dr_mod(void) 17030a5701edSNadav Amit { 17040a5701edSNadav Amit MK_INSN(drmod, "movl %ebx, %dr0\n\t" 17050a5701edSNadav Amit ".byte 0x0f \n\t .byte 0x21 \n\t .byte 0x0\n\t"); 1706bd62e289SBill Wendling 1707bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0xdead, .ebx = 0xaced }); 1708bd62e289SBill Wendling 17090a5701edSNadav Amit exec_in_big_real_mode(&insn_drmod); 17100a5701edSNadav Amit report("mov dr with mod bits", R_AX | R_BX, outregs.eax == 0xaced); 17110a5701edSNadav Amit } 17120a5701edSNadav Amit 17132e3f9f1fSThomas Huth static void test_smsw(void) 171499ee878cSNadav Amit { 171599ee878cSNadav Amit MK_INSN(smsw, "movl %cr0, %ebx\n\t" 171699ee878cSNadav Amit "movl %ebx, %ecx\n\t" 171799ee878cSNadav Amit "or $0x40000000, %ebx\n\t" 171899ee878cSNadav Amit "movl %ebx, %cr0\n\t" 171999ee878cSNadav Amit "smswl %eax\n\t" 172099ee878cSNadav Amit "movl %ecx, %cr0\n\t"); 1721bd62e289SBill Wendling 1722bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x12345678 }); 1723bd62e289SBill Wendling 172499ee878cSNadav Amit exec_in_big_real_mode(&insn_smsw); 172599ee878cSNadav Amit report("smsw", R_AX | R_BX | R_CX, outregs.eax == outregs.ebx); 172699ee878cSNadav Amit } 172799ee878cSNadav Amit 17282e3f9f1fSThomas Huth static void test_xadd(void) 17297bee560dSNadav Amit { 17307bee560dSNadav Amit MK_INSN(xadd, "xaddl %eax, %eax\n\t"); 1731bd62e289SBill Wendling 1732bd62e289SBill Wendling init_inregs(&(struct regs){ .eax = 0x12345678 }); 1733bd62e289SBill Wendling 17347bee560dSNadav Amit exec_in_big_real_mode(&insn_xadd); 17357bee560dSNadav Amit report("xadd", R_AX, outregs.eax == inregs.eax * 2); 17367bee560dSNadav Amit } 17377bee560dSNadav Amit 173899ee878cSNadav Amit 17397d36db35SAvi Kivity void realmode_start(void) 17407d36db35SAvi Kivity { 17417d36db35SAvi Kivity test_null(); 17427d36db35SAvi Kivity 17437d36db35SAvi Kivity test_shld(); 17447d36db35SAvi Kivity test_push_pop(); 17457d36db35SAvi Kivity test_pusha_popa(); 17467d36db35SAvi Kivity test_mov_imm(); 17477d36db35SAvi Kivity test_cmp_imm(); 17487d36db35SAvi Kivity test_add_imm(); 17497d36db35SAvi Kivity test_sub_imm(); 17507d36db35SAvi Kivity test_xor_imm(); 17517d36db35SAvi Kivity test_io(); 17527d36db35SAvi Kivity test_eflags_insn(); 17537d36db35SAvi Kivity test_jcc_short(); 17547d36db35SAvi Kivity test_jcc_near(); 17557d36db35SAvi Kivity /* test_call() uses short jump so call it after testing jcc */ 17567d36db35SAvi Kivity test_call(); 17577d36db35SAvi Kivity /* long jmp test uses call near so test it after testing call */ 17587d36db35SAvi Kivity test_long_jmp(); 17597d36db35SAvi Kivity test_xchg(); 17607d36db35SAvi Kivity test_iret(); 176196b9ca1eSMohammed Gamal test_int(); 17628202cf84SRoman Bolshakov test_sti_inhibit(); 1763fa74f8a6SMohammed Gamal test_imul(); 176459317bd1SMohammed Gamal test_mul(); 17650d4c7614SMohammed Gamal test_div(); 17660d4c7614SMohammed Gamal test_idiv(); 1767eacef4e2SWei Yongjun test_loopcc(); 17686e293cf5SWei Yongjun test_cbw(); 17690cbd5b06SMohammed Gamal test_cwd_cdq(); 1770b274feedSAvi Kivity test_das(); 177137f51a4aSWei Yongjun test_lds_lss(); 1772b1c7c575SWei Yongjun test_jcxz(); 17738f578e98SAvi Kivity test_cpuid(); 1774ed93f43bSAvi Kivity test_ss_base_for_esp_ebp(); 1775c2281fa4SAvi Kivity test_sgdt_sidt(); 17767ae3645aSAvi Kivity test_lahf(); 177788b6dac4SPaolo Bonzini test_sahf(); 1778fd9ea640SAvi Kivity test_movzx_movsx(); 1779b493b2e8SAvi Kivity test_bswap(); 17808cd86387SGleb Natapov test_aad(); 17812a9b5718SPaolo Bonzini test_aam(); 17822a9b5718SPaolo Bonzini test_xlat(); 17832a9b5718SPaolo Bonzini test_salc(); 17840987db7aSGleb Natapov test_fninit(); 17850a5701edSNadav Amit test_dr_mod(); 178699ee878cSNadav Amit test_smsw(); 17871a4c03a0SArthur Chunqi Li test_nopl(); 17887bee560dSNadav Amit test_xadd(); 1789b5105e8bSPaolo Bonzini test_perf_loop(); 1790b5105e8bSPaolo Bonzini test_perf_mov(); 1791b5105e8bSPaolo Bonzini test_perf_arith(); 1792b5105e8bSPaolo Bonzini test_perf_memory_load(); 17939306cb8eSPaolo Bonzini test_perf_memory_store(); 1794b5105e8bSPaolo Bonzini test_perf_memory_rmw(); 17957d36db35SAvi Kivity 1796b393fe28SNadav Amit exit(failed); 17977d36db35SAvi Kivity } 17987d36db35SAvi Kivity 17997d36db35SAvi Kivity unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff }; 18007d36db35SAvi Kivity 1801975ca087SPeter Feiner struct table_descr r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt }; 18027d36db35SAvi Kivity 18037d36db35SAvi Kivity asm( 18047d36db35SAvi Kivity ".section .init \n\t" 18057d36db35SAvi Kivity 18067d36db35SAvi Kivity ".code32 \n\t" 18077d36db35SAvi Kivity 18087d36db35SAvi Kivity "mb_magic = 0x1BADB002 \n\t" 18097d36db35SAvi Kivity "mb_flags = 0x0 \n\t" 18107d36db35SAvi Kivity 18117d36db35SAvi Kivity "# multiboot header \n\t" 18127d36db35SAvi Kivity ".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t" 18137d36db35SAvi Kivity 18147d36db35SAvi Kivity ".globl start \n\t" 18157d36db35SAvi Kivity ".data \n\t" 18167d36db35SAvi Kivity ". = . + 4096 \n\t" 18177d36db35SAvi Kivity "stacktop: \n\t" 18187d36db35SAvi Kivity 18197d36db35SAvi Kivity ".text \n\t" 18207d36db35SAvi Kivity "start: \n\t" 18217d36db35SAvi Kivity "lgdt r_gdt_descr \n\t" 18227d36db35SAvi Kivity "ljmp $8, $1f; 1: \n\t" 18237d36db35SAvi Kivity ".code16gcc \n\t" 18247d36db35SAvi Kivity "mov $16, %eax \n\t" 18257d36db35SAvi Kivity "mov %ax, %ds \n\t" 18267d36db35SAvi Kivity "mov %ax, %es \n\t" 18277d36db35SAvi Kivity "mov %ax, %fs \n\t" 18287d36db35SAvi Kivity "mov %ax, %gs \n\t" 18297d36db35SAvi Kivity "mov %ax, %ss \n\t" 18307d36db35SAvi Kivity "mov %cr0, %eax \n\t" 18317d36db35SAvi Kivity "btc $0, %eax \n\t" 18327d36db35SAvi Kivity "mov %eax, %cr0 \n\t" 18337d36db35SAvi Kivity "ljmp $0, $realmode_entry \n\t" 18347d36db35SAvi Kivity 18357d36db35SAvi Kivity "realmode_entry: \n\t" 18367d36db35SAvi Kivity 18377d36db35SAvi Kivity "xor %ax, %ax \n\t" 18387d36db35SAvi Kivity "mov %ax, %ds \n\t" 18397d36db35SAvi Kivity "mov %ax, %es \n\t" 18407d36db35SAvi Kivity "mov %ax, %ss \n\t" 18417d36db35SAvi Kivity "mov %ax, %fs \n\t" 18427d36db35SAvi Kivity "mov %ax, %gs \n\t" 18437d36db35SAvi Kivity "mov $stacktop, %esp\n\t" 18447d36db35SAvi Kivity "ljmp $0, $realmode_start \n\t" 18457d36db35SAvi Kivity 18467d36db35SAvi Kivity ".code16gcc \n\t" 18477d36db35SAvi Kivity ); 1848