Commit ba1c6e37fc5efc0f3d1e50d0760f9f4a1061187b
1 parent
927f621e
test infrastructure
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@16 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
194 additions
and
43 deletions
cpu-i386.h
| @@ -85,7 +85,7 @@ typedef long double CPU86_LDouble; | @@ -85,7 +85,7 @@ typedef long double CPU86_LDouble; | ||
| 85 | typedef double CPU86_LDouble; | 85 | typedef double CPU86_LDouble; |
| 86 | #endif | 86 | #endif |
| 87 | 87 | ||
| 88 | -typedef struct CPU86State { | 88 | +typedef struct CPUX86State { |
| 89 | /* standard registers */ | 89 | /* standard registers */ |
| 90 | uint32_t regs[8]; | 90 | uint32_t regs[8]; |
| 91 | uint32_t pc; /* cs_case + eip value */ | 91 | uint32_t pc; /* cs_case + eip value */ |
| @@ -109,11 +109,8 @@ typedef struct CPU86State { | @@ -109,11 +109,8 @@ typedef struct CPU86State { | ||
| 109 | unsigned int fpuc; | 109 | unsigned int fpuc; |
| 110 | 110 | ||
| 111 | /* emulator internal variables */ | 111 | /* emulator internal variables */ |
| 112 | - uint32_t t0; /* temporary t0 storage */ | ||
| 113 | - uint32_t t1; /* temporary t1 storage */ | ||
| 114 | - uint32_t a0; /* temporary a0 storage (address) */ | ||
| 115 | CPU86_LDouble ft0; | 112 | CPU86_LDouble ft0; |
| 116 | -} CPU86State; | 113 | +} CPUX86State; |
| 117 | 114 | ||
| 118 | static inline int ldub(void *ptr) | 115 | static inline int ldub(void *ptr) |
| 119 | { | 116 | { |
| @@ -188,12 +185,20 @@ static inline void stfq(void *ptr, double v) | @@ -188,12 +185,20 @@ static inline void stfq(void *ptr, double v) | ||
| 188 | } | 185 | } |
| 189 | 186 | ||
| 190 | #ifndef IN_OP_I386 | 187 | #ifndef IN_OP_I386 |
| 191 | -void port_outb(int addr, int val); | ||
| 192 | -void port_outw(int addr, int val); | ||
| 193 | -void port_outl(int addr, int val); | ||
| 194 | -int port_inb(int addr); | ||
| 195 | -int port_inw(int addr); | ||
| 196 | -int port_inl(int addr); | 188 | +void cpu_x86_outb(int addr, int val); |
| 189 | +void cpu_x86_outw(int addr, int val); | ||
| 190 | +void cpu_x86_outl(int addr, int val); | ||
| 191 | +int cpu_x86_inb(int addr); | ||
| 192 | +int cpu_x86_inw(int addr); | ||
| 193 | +int cpu_x86_inl(int addr); | ||
| 197 | #endif | 194 | #endif |
| 198 | 195 | ||
| 196 | +CPUX86State *cpu_x86_init(void); | ||
| 197 | +int cpu_x86_exec(CPUX86State *s); | ||
| 198 | +void cpu_x86_close(CPUX86State *s); | ||
| 199 | + | ||
| 200 | +/* internal functions */ | ||
| 201 | +int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, | ||
| 202 | + uint8_t *pc_start); | ||
| 203 | + | ||
| 199 | #endif /* CPU_I386_H */ | 204 | #endif /* CPU_I386_H */ |
linux-user/main.c
| @@ -193,34 +193,34 @@ void INT_handler(int num, void *env) | @@ -193,34 +193,34 @@ void INT_handler(int num, void *env) | ||
| 193 | /***********************************************************/ | 193 | /***********************************************************/ |
| 194 | /* new CPU core */ | 194 | /* new CPU core */ |
| 195 | 195 | ||
| 196 | -void port_outb(int addr, int val) | 196 | +void cpu_x86_outb(int addr, int val) |
| 197 | { | 197 | { |
| 198 | fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); | 198 | fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | -void port_outw(int addr, int val) | 201 | +void cpu_x86_outw(int addr, int val) |
| 202 | { | 202 | { |
| 203 | fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); | 203 | fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | -void port_outl(int addr, int val) | 206 | +void cpu_x86_outl(int addr, int val) |
| 207 | { | 207 | { |
| 208 | fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); | 208 | fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | -int port_inb(int addr) | 211 | +int cpu_x86_inb(int addr) |
| 212 | { | 212 | { |
| 213 | fprintf(stderr, "inb: port=0x%04x\n", addr); | 213 | fprintf(stderr, "inb: port=0x%04x\n", addr); |
| 214 | return 0; | 214 | return 0; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | -int port_inw(int addr) | 217 | +int cpu_x86_inw(int addr) |
| 218 | { | 218 | { |
| 219 | fprintf(stderr, "inw: port=0x%04x\n", addr); | 219 | fprintf(stderr, "inw: port=0x%04x\n", addr); |
| 220 | return 0; | 220 | return 0; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | -int port_inl(int addr) | 223 | +int cpu_x86_inl(int addr) |
| 224 | { | 224 | { |
| 225 | fprintf(stderr, "inl: port=0x%04x\n", addr); | 225 | fprintf(stderr, "inl: port=0x%04x\n", addr); |
| 226 | return 0; | 226 | return 0; |
op-i386.c
| @@ -10,39 +10,44 @@ typedef signed long long int64_t; | @@ -10,39 +10,44 @@ typedef signed long long int64_t; | ||
| 10 | 10 | ||
| 11 | #define NULL 0 | 11 | #define NULL 0 |
| 12 | 12 | ||
| 13 | +typedef struct FILE FILE; | ||
| 14 | + | ||
| 15 | +extern FILE *stderr; | ||
| 16 | +extern int fprintf(FILE *, const char *, ...); | ||
| 17 | + | ||
| 13 | #ifdef __i386__ | 18 | #ifdef __i386__ |
| 14 | register int T0 asm("esi"); | 19 | register int T0 asm("esi"); |
| 15 | register int T1 asm("ebx"); | 20 | register int T1 asm("ebx"); |
| 16 | register int A0 asm("edi"); | 21 | register int A0 asm("edi"); |
| 17 | -register struct CPU86State *env asm("ebp"); | 22 | +register struct CPUX86State *env asm("ebp"); |
| 18 | #define FORCE_RET() asm volatile ("ret"); | 23 | #define FORCE_RET() asm volatile ("ret"); |
| 19 | #endif | 24 | #endif |
| 20 | #ifdef __powerpc__ | 25 | #ifdef __powerpc__ |
| 21 | register int T0 asm("r24"); | 26 | register int T0 asm("r24"); |
| 22 | register int T1 asm("r25"); | 27 | register int T1 asm("r25"); |
| 23 | register int A0 asm("r26"); | 28 | register int A0 asm("r26"); |
| 24 | -register struct CPU86State *env asm("r27"); | 29 | +register struct CPUX86State *env asm("r27"); |
| 25 | #define FORCE_RET() asm volatile ("blr"); | 30 | #define FORCE_RET() asm volatile ("blr"); |
| 26 | #endif | 31 | #endif |
| 27 | #ifdef __arm__ | 32 | #ifdef __arm__ |
| 28 | register int T0 asm("r4"); | 33 | register int T0 asm("r4"); |
| 29 | register int T1 asm("r5"); | 34 | register int T1 asm("r5"); |
| 30 | register int A0 asm("r6"); | 35 | register int A0 asm("r6"); |
| 31 | -register struct CPU86State *env asm("r7"); | 36 | +register struct CPUX86State *env asm("r7"); |
| 32 | #define FORCE_RET() asm volatile ("mov pc, lr"); | 37 | #define FORCE_RET() asm volatile ("mov pc, lr"); |
| 33 | #endif | 38 | #endif |
| 34 | #ifdef __mips__ | 39 | #ifdef __mips__ |
| 35 | register int T0 asm("s0"); | 40 | register int T0 asm("s0"); |
| 36 | register int T1 asm("s1"); | 41 | register int T1 asm("s1"); |
| 37 | register int A0 asm("s2"); | 42 | register int A0 asm("s2"); |
| 38 | -register struct CPU86State *env asm("s3"); | 43 | +register struct CPUX86State *env asm("s3"); |
| 39 | #define FORCE_RET() asm volatile ("jr $31"); | 44 | #define FORCE_RET() asm volatile ("jr $31"); |
| 40 | #endif | 45 | #endif |
| 41 | #ifdef __sparc__ | 46 | #ifdef __sparc__ |
| 42 | register int T0 asm("l0"); | 47 | register int T0 asm("l0"); |
| 43 | register int T1 asm("l1"); | 48 | register int T1 asm("l1"); |
| 44 | register int A0 asm("l2"); | 49 | register int A0 asm("l2"); |
| 45 | -register struct CPU86State *env asm("l3"); | 50 | +register struct CPUX86State *env asm("l3"); |
| 46 | #define FORCE_RET() asm volatile ("retl ; nop"); | 51 | #define FORCE_RET() asm volatile ("retl ; nop"); |
| 47 | #endif | 52 | #endif |
| 48 | 53 | ||
| @@ -465,17 +470,17 @@ void OPPROTO op_idivl_EAX_T0(void) | @@ -465,17 +470,17 @@ void OPPROTO op_idivl_EAX_T0(void) | ||
| 465 | 470 | ||
| 466 | /* constant load */ | 471 | /* constant load */ |
| 467 | 472 | ||
| 468 | -void OPPROTO op1_movl_T0_im(void) | 473 | +void OPPROTO op_movl_T0_im(void) |
| 469 | { | 474 | { |
| 470 | T0 = PARAM1; | 475 | T0 = PARAM1; |
| 471 | } | 476 | } |
| 472 | 477 | ||
| 473 | -void OPPROTO op1_movl_T1_im(void) | 478 | +void OPPROTO op_movl_T1_im(void) |
| 474 | { | 479 | { |
| 475 | T1 = PARAM1; | 480 | T1 = PARAM1; |
| 476 | } | 481 | } |
| 477 | 482 | ||
| 478 | -void OPPROTO op1_movl_A0_im(void) | 483 | +void OPPROTO op_movl_A0_im(void) |
| 479 | { | 484 | { |
| 480 | A0 = PARAM1; | 485 | A0 = PARAM1; |
| 481 | } | 486 | } |
| @@ -1592,3 +1597,35 @@ void OPPROTO op_fcos(void) | @@ -1592,3 +1597,35 @@ void OPPROTO op_fcos(void) | ||
| 1592 | helper_fcos(); | 1597 | helper_fcos(); |
| 1593 | } | 1598 | } |
| 1594 | 1599 | ||
| 1600 | +/* main execution loop */ | ||
| 1601 | +uint8_t code_gen_buffer[65536]; | ||
| 1602 | + | ||
| 1603 | + | ||
| 1604 | +int cpu_x86_exec(CPUX86State *env1) | ||
| 1605 | +{ | ||
| 1606 | + int saved_T0, saved_T1, saved_A0; | ||
| 1607 | + CPUX86State *saved_env; | ||
| 1608 | + int code_gen_size; | ||
| 1609 | + void (*gen_func)(void); | ||
| 1610 | + | ||
| 1611 | + /* first we save global registers */ | ||
| 1612 | + saved_T0 = T0; | ||
| 1613 | + saved_T1 = T1; | ||
| 1614 | + saved_A0 = A0; | ||
| 1615 | + saved_env = env; | ||
| 1616 | + env = env1; | ||
| 1617 | + | ||
| 1618 | + for(;;) { | ||
| 1619 | + cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc); | ||
| 1620 | + /* execute the generated code */ | ||
| 1621 | + gen_func = (void *)code_gen_buffer; | ||
| 1622 | + gen_func(); | ||
| 1623 | + } | ||
| 1624 | + | ||
| 1625 | + /* restore global registers */ | ||
| 1626 | + T0 = saved_T0; | ||
| 1627 | + T1 = saved_T1; | ||
| 1628 | + A0 = saved_A0; | ||
| 1629 | + env = saved_env; | ||
| 1630 | + return 0; | ||
| 1631 | +} |
ops_template.h
| @@ -575,12 +575,14 @@ void OPPROTO glue(op_repnz_cmps, SUFFIX)(void) | @@ -575,12 +575,14 @@ void OPPROTO glue(op_repnz_cmps, SUFFIX)(void) | ||
| 575 | } | 575 | } |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | +/* port I/O */ | ||
| 579 | + | ||
| 578 | void OPPROTO glue(op_outs, SUFFIX)(void) | 580 | void OPPROTO glue(op_outs, SUFFIX)(void) |
| 579 | { | 581 | { |
| 580 | int v, dx; | 582 | int v, dx; |
| 581 | dx = EDX & 0xffff; | 583 | dx = EDX & 0xffff; |
| 582 | v = glue(ldu, SUFFIX)((void *)ESI); | 584 | v = glue(ldu, SUFFIX)((void *)ESI); |
| 583 | - glue(port_out, SUFFIX)(dx, v); | 585 | + glue(cpu_x86_out, SUFFIX)(dx, v); |
| 584 | ESI += (DF << SHIFT); | 586 | ESI += (DF << SHIFT); |
| 585 | } | 587 | } |
| 586 | 588 | ||
| @@ -591,7 +593,7 @@ void OPPROTO glue(op_rep_outs, SUFFIX)(void) | @@ -591,7 +593,7 @@ void OPPROTO glue(op_rep_outs, SUFFIX)(void) | ||
| 591 | dx = EDX & 0xffff; | 593 | dx = EDX & 0xffff; |
| 592 | while (ECX != 0) { | 594 | while (ECX != 0) { |
| 593 | v = glue(ldu, SUFFIX)((void *)ESI); | 595 | v = glue(ldu, SUFFIX)((void *)ESI); |
| 594 | - glue(port_out, SUFFIX)(dx, v); | 596 | + glue(cpu_x86_out, SUFFIX)(dx, v); |
| 595 | ESI += inc; | 597 | ESI += inc; |
| 596 | ECX--; | 598 | ECX--; |
| 597 | } | 599 | } |
| @@ -601,7 +603,7 @@ void OPPROTO glue(op_ins, SUFFIX)(void) | @@ -601,7 +603,7 @@ void OPPROTO glue(op_ins, SUFFIX)(void) | ||
| 601 | { | 603 | { |
| 602 | int v, dx; | 604 | int v, dx; |
| 603 | dx = EDX & 0xffff; | 605 | dx = EDX & 0xffff; |
| 604 | - v = glue(port_in, SUFFIX)(dx); | 606 | + v = glue(cpu_x86_in, SUFFIX)(dx); |
| 605 | glue(st, SUFFIX)((void *)EDI, v); | 607 | glue(st, SUFFIX)((void *)EDI, v); |
| 606 | EDI += (DF << SHIFT); | 608 | EDI += (DF << SHIFT); |
| 607 | } | 609 | } |
| @@ -612,13 +614,23 @@ void OPPROTO glue(op_rep_ins, SUFFIX)(void) | @@ -612,13 +614,23 @@ void OPPROTO glue(op_rep_ins, SUFFIX)(void) | ||
| 612 | inc = (DF << SHIFT); | 614 | inc = (DF << SHIFT); |
| 613 | dx = EDX & 0xffff; | 615 | dx = EDX & 0xffff; |
| 614 | while (ECX != 0) { | 616 | while (ECX != 0) { |
| 615 | - v = glue(port_in, SUFFIX)(dx); | 617 | + v = glue(cpu_x86_in, SUFFIX)(dx); |
| 616 | glue(st, SUFFIX)((void *)EDI, v); | 618 | glue(st, SUFFIX)((void *)EDI, v); |
| 617 | EDI += (DF << SHIFT); | 619 | EDI += (DF << SHIFT); |
| 618 | ECX--; | 620 | ECX--; |
| 619 | } | 621 | } |
| 620 | } | 622 | } |
| 621 | 623 | ||
| 624 | +void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void) | ||
| 625 | +{ | ||
| 626 | + glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK); | ||
| 627 | +} | ||
| 628 | + | ||
| 629 | +void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void) | ||
| 630 | +{ | ||
| 631 | + T1 = glue(cpu_x86_in, SUFFIX)(T0 & 0xffff); | ||
| 632 | +} | ||
| 633 | + | ||
| 622 | #undef DATA_BITS | 634 | #undef DATA_BITS |
| 623 | #undef SHIFT_MASK | 635 | #undef SHIFT_MASK |
| 624 | #undef SIGN_MASK | 636 | #undef SIGN_MASK |
translate-i386.c
| @@ -495,6 +495,18 @@ static GenOpFunc *gen_op_outs[6] = { | @@ -495,6 +495,18 @@ static GenOpFunc *gen_op_outs[6] = { | ||
| 495 | gen_op_rep_outsl, | 495 | gen_op_rep_outsl, |
| 496 | }; | 496 | }; |
| 497 | 497 | ||
| 498 | +static GenOpFunc *gen_op_in[3] = { | ||
| 499 | + gen_op_inb_T0_T1, | ||
| 500 | + gen_op_inw_T0_T1, | ||
| 501 | + gen_op_inl_T0_T1, | ||
| 502 | +}; | ||
| 503 | + | ||
| 504 | +static GenOpFunc *gen_op_out[3] = { | ||
| 505 | + gen_op_outb_T0_T1, | ||
| 506 | + gen_op_outw_T0_T1, | ||
| 507 | + gen_op_outl_T0_T1, | ||
| 508 | +}; | ||
| 509 | + | ||
| 498 | enum { | 510 | enum { |
| 499 | JCC_O, | 511 | JCC_O, |
| 500 | JCC_B, | 512 | JCC_B, |
| @@ -632,7 +644,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d, int s) | @@ -632,7 +644,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d, int s) | ||
| 632 | 644 | ||
| 633 | static void gen_opi(DisasContext *s1, int op, int ot, int d, int c) | 645 | static void gen_opi(DisasContext *s1, int op, int ot, int d, int c) |
| 634 | { | 646 | { |
| 635 | - gen_op1_movl_T1_im(c); | 647 | + gen_op_movl_T1_im(c); |
| 636 | gen_op(s1, op, ot, d, OR_TMP0); | 648 | gen_op(s1, op, ot, d, OR_TMP0); |
| 637 | } | 649 | } |
| 638 | 650 | ||
| @@ -678,7 +690,7 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) | @@ -678,7 +690,7 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) | ||
| 678 | static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c) | 690 | static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c) |
| 679 | { | 691 | { |
| 680 | /* currently not optimized */ | 692 | /* currently not optimized */ |
| 681 | - gen_op1_movl_T1_im(c); | 693 | + gen_op_movl_T1_im(c); |
| 682 | gen_shift(s1, op, ot, d, OR_TMP1); | 694 | gen_shift(s1, op, ot, d, OR_TMP1); |
| 683 | } | 695 | } |
| 684 | 696 | ||
| @@ -746,7 +758,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | @@ -746,7 +758,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | ||
| 746 | if (reg2 == OR_ZERO) { | 758 | if (reg2 == OR_ZERO) { |
| 747 | /* op: disp + (reg1 << scale) */ | 759 | /* op: disp + (reg1 << scale) */ |
| 748 | if (reg1 == OR_ZERO) { | 760 | if (reg1 == OR_ZERO) { |
| 749 | - gen_op1_movl_A0_im(disp); | 761 | + gen_op_movl_A0_im(disp); |
| 750 | } else if (scale == 0 && disp == 0) { | 762 | } else if (scale == 0 && disp == 0) { |
| 751 | gen_op_movl_A0_reg[reg1](); | 763 | gen_op_movl_A0_reg[reg1](); |
| 752 | } else { | 764 | } else { |
| @@ -755,7 +767,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | @@ -755,7 +767,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | ||
| 755 | } else { | 767 | } else { |
| 756 | /* op: disp + reg1 + (reg2 << scale) */ | 768 | /* op: disp + reg1 + (reg2 << scale) */ |
| 757 | if (disp != 0) { | 769 | if (disp != 0) { |
| 758 | - gen_op1_movl_A0_im(disp); | 770 | + gen_op_movl_A0_im(disp); |
| 759 | gen_op_addl_A0_reg_sN[0][reg1](); | 771 | gen_op_addl_A0_reg_sN[0][reg1](); |
| 760 | } else { | 772 | } else { |
| 761 | gen_op_movl_A0_reg[reg1](); | 773 | gen_op_movl_A0_reg[reg1](); |
| @@ -1149,7 +1161,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1149,7 +1161,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 1149 | switch(op) { | 1161 | switch(op) { |
| 1150 | case 0: /* test */ | 1162 | case 0: /* test */ |
| 1151 | val = insn_get(s, ot); | 1163 | val = insn_get(s, ot); |
| 1152 | - gen_op1_movl_T1_im(val); | 1164 | + gen_op_movl_T1_im(val); |
| 1153 | gen_op_testl_T0_T1_cc(); | 1165 | gen_op_testl_T0_T1_cc(); |
| 1154 | s->cc_op = CC_OP_LOGICB + ot; | 1166 | s->cc_op = CC_OP_LOGICB + ot; |
| 1155 | break; | 1167 | break; |
| @@ -1266,7 +1278,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1266,7 +1278,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 1266 | gen_op_st_T0_A0[ot](); | 1278 | gen_op_st_T0_A0[ot](); |
| 1267 | break; | 1279 | break; |
| 1268 | case 2: /* call Ev */ | 1280 | case 2: /* call Ev */ |
| 1269 | - gen_op1_movl_T1_im((long)s->pc); | 1281 | + gen_op_movl_T1_im((long)s->pc); |
| 1270 | gen_op_pushl_T1(); | 1282 | gen_op_pushl_T1(); |
| 1271 | gen_op_jmp_T0(); | 1283 | gen_op_jmp_T0(); |
| 1272 | break; | 1284 | break; |
| @@ -1309,7 +1321,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1309,7 +1321,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 1309 | val = insn_get(s, ot); | 1321 | val = insn_get(s, ot); |
| 1310 | 1322 | ||
| 1311 | gen_op_mov_TN_reg[ot][0][OR_EAX](); | 1323 | gen_op_mov_TN_reg[ot][0][OR_EAX](); |
| 1312 | - gen_op1_movl_T1_im(val); | 1324 | + gen_op_movl_T1_im(val); |
| 1313 | gen_op_testl_T0_T1_cc(); | 1325 | gen_op_testl_T0_T1_cc(); |
| 1314 | s->cc_op = CC_OP_LOGICB + ot; | 1326 | s->cc_op = CC_OP_LOGICB + ot; |
| 1315 | break; | 1327 | break; |
| @@ -1336,10 +1348,10 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1336,10 +1348,10 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 1336 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); | 1348 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); |
| 1337 | if (b == 0x69) { | 1349 | if (b == 0x69) { |
| 1338 | val = insn_get(s, ot); | 1350 | val = insn_get(s, ot); |
| 1339 | - gen_op1_movl_T1_im(val); | 1351 | + gen_op_movl_T1_im(val); |
| 1340 | } else if (b == 0x6b) { | 1352 | } else if (b == 0x6b) { |
| 1341 | val = insn_get(s, OT_BYTE); | 1353 | val = insn_get(s, OT_BYTE); |
| 1342 | - gen_op1_movl_T1_im(val); | 1354 | + gen_op_movl_T1_im(val); |
| 1343 | } else { | 1355 | } else { |
| 1344 | gen_op_mov_TN_reg[ot][1][reg](); | 1356 | gen_op_mov_TN_reg[ot][1][reg](); |
| 1345 | } | 1357 | } |
| @@ -1369,7 +1381,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1369,7 +1381,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 1369 | val = insn_get(s, ot); | 1381 | val = insn_get(s, ot); |
| 1370 | else | 1382 | else |
| 1371 | val = (int8_t)insn_get(s, OT_BYTE); | 1383 | val = (int8_t)insn_get(s, OT_BYTE); |
| 1372 | - gen_op1_movl_T0_im(val); | 1384 | + gen_op_movl_T0_im(val); |
| 1373 | gen_op_pushl_T0(); | 1385 | gen_op_pushl_T0(); |
| 1374 | break; | 1386 | break; |
| 1375 | case 0x8f: /* pop Ev */ | 1387 | case 0x8f: /* pop Ev */ |
| @@ -1408,7 +1420,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1408,7 +1420,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 1408 | mod = (modrm >> 6) & 3; | 1420 | mod = (modrm >> 6) & 3; |
| 1409 | 1421 | ||
| 1410 | val = insn_get(s, ot); | 1422 | val = insn_get(s, ot); |
| 1411 | - gen_op1_movl_T0_im(val); | 1423 | + gen_op_movl_T0_im(val); |
| 1412 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); | 1424 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); |
| 1413 | break; | 1425 | break; |
| 1414 | case 0x8a: | 1426 | case 0x8a: |
| @@ -1502,14 +1514,14 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1502,14 +1514,14 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 1502 | 1514 | ||
| 1503 | case 0xb0 ... 0xb7: /* mov R, Ib */ | 1515 | case 0xb0 ... 0xb7: /* mov R, Ib */ |
| 1504 | val = insn_get(s, OT_BYTE); | 1516 | val = insn_get(s, OT_BYTE); |
| 1505 | - gen_op1_movl_T0_im(val); | 1517 | + gen_op_movl_T0_im(val); |
| 1506 | gen_op_mov_reg_T0[OT_BYTE][b & 7](); | 1518 | gen_op_mov_reg_T0[OT_BYTE][b & 7](); |
| 1507 | break; | 1519 | break; |
| 1508 | case 0xb8 ... 0xbf: /* mov R, Iv */ | 1520 | case 0xb8 ... 0xbf: /* mov R, Iv */ |
| 1509 | ot = dflag ? OT_LONG : OT_WORD; | 1521 | ot = dflag ? OT_LONG : OT_WORD; |
| 1510 | val = insn_get(s, ot); | 1522 | val = insn_get(s, ot); |
| 1511 | reg = OR_EAX + (b & 7); | 1523 | reg = OR_EAX + (b & 7); |
| 1512 | - gen_op1_movl_T0_im(val); | 1524 | + gen_op_movl_T0_im(val); |
| 1513 | gen_op_mov_reg_T0[ot][reg](); | 1525 | gen_op_mov_reg_T0[ot][reg](); |
| 1514 | break; | 1526 | break; |
| 1515 | 1527 | ||
| @@ -1978,6 +1990,8 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1978,6 +1990,8 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 1978 | } | 1990 | } |
| 1979 | break; | 1991 | break; |
| 1980 | 1992 | ||
| 1993 | + /************************/ | ||
| 1994 | + /* port I/O */ | ||
| 1981 | case 0x6c: /* insS */ | 1995 | case 0x6c: /* insS */ |
| 1982 | case 0x6d: | 1996 | case 0x6d: |
| 1983 | if ((b & 1) == 0) | 1997 | if ((b & 1) == 0) |
| @@ -2002,6 +2016,48 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2002,6 +2016,48 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 2002 | gen_op_outs[ot](); | 2016 | gen_op_outs[ot](); |
| 2003 | } | 2017 | } |
| 2004 | break; | 2018 | break; |
| 2019 | + case 0xe4: | ||
| 2020 | + case 0xe5: | ||
| 2021 | + if ((b & 1) == 0) | ||
| 2022 | + ot = OT_BYTE; | ||
| 2023 | + else | ||
| 2024 | + ot = dflag ? OT_LONG : OT_WORD; | ||
| 2025 | + val = ldub(s->pc++); | ||
| 2026 | + gen_op_movl_T0_im(val); | ||
| 2027 | + gen_op_in[ot](); | ||
| 2028 | + gen_op_mov_reg_T1[ot][R_EAX](); | ||
| 2029 | + break; | ||
| 2030 | + case 0xe6: | ||
| 2031 | + case 0xe7: | ||
| 2032 | + if ((b & 1) == 0) | ||
| 2033 | + ot = OT_BYTE; | ||
| 2034 | + else | ||
| 2035 | + ot = dflag ? OT_LONG : OT_WORD; | ||
| 2036 | + val = ldub(s->pc++); | ||
| 2037 | + gen_op_movl_T0_im(val); | ||
| 2038 | + gen_op_mov_TN_reg[ot][1][R_EAX](); | ||
| 2039 | + gen_op_out[ot](); | ||
| 2040 | + break; | ||
| 2041 | + case 0xec: | ||
| 2042 | + case 0xed: | ||
| 2043 | + if ((b & 1) == 0) | ||
| 2044 | + ot = OT_BYTE; | ||
| 2045 | + else | ||
| 2046 | + ot = dflag ? OT_LONG : OT_WORD; | ||
| 2047 | + gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); | ||
| 2048 | + gen_op_in[ot](); | ||
| 2049 | + gen_op_mov_reg_T1[ot][R_EAX](); | ||
| 2050 | + break; | ||
| 2051 | + case 0xee: | ||
| 2052 | + case 0xef: | ||
| 2053 | + if ((b & 1) == 0) | ||
| 2054 | + ot = OT_BYTE; | ||
| 2055 | + else | ||
| 2056 | + ot = dflag ? OT_LONG : OT_WORD; | ||
| 2057 | + gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); | ||
| 2058 | + gen_op_mov_TN_reg[ot][1][R_EAX](); | ||
| 2059 | + gen_op_out[ot](); | ||
| 2060 | + break; | ||
| 2005 | 2061 | ||
| 2006 | /************************/ | 2062 | /************************/ |
| 2007 | /* control */ | 2063 | /* control */ |
| @@ -2020,7 +2076,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2020,7 +2076,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 2020 | case 0xe8: /* call */ | 2076 | case 0xe8: /* call */ |
| 2021 | val = insn_get(s, OT_LONG); | 2077 | val = insn_get(s, OT_LONG); |
| 2022 | val += (long)s->pc; | 2078 | val += (long)s->pc; |
| 2023 | - gen_op1_movl_T1_im((long)s->pc); | 2079 | + gen_op_movl_T1_im((long)s->pc); |
| 2024 | gen_op_pushl_T1(); | 2080 | gen_op_pushl_T1(); |
| 2025 | gen_op_jmp_im(val); | 2081 | gen_op_jmp_im(val); |
| 2026 | break; | 2082 | break; |
| @@ -2121,3 +2177,44 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2121,3 +2177,44 @@ int disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 2121 | return (long)s->pc; | 2177 | return (long)s->pc; |
| 2122 | } | 2178 | } |
| 2123 | 2179 | ||
| 2180 | +/* return the next pc */ | ||
| 2181 | +int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, | ||
| 2182 | + uint8_t *pc_start) | ||
| 2183 | +{ | ||
| 2184 | + DisasContext dc1, *dc = &dc1; | ||
| 2185 | + long ret; | ||
| 2186 | + dc->cc_op = CC_OP_DYNAMIC; | ||
| 2187 | + gen_code_ptr = gen_code_buf; | ||
| 2188 | + gen_start(); | ||
| 2189 | + ret = disas_insn(dc, pc_start); | ||
| 2190 | + if (ret == -1) | ||
| 2191 | + error("unknown instruction at PC=0x%x", pc_start); | ||
| 2192 | + gen_end(); | ||
| 2193 | + *gen_code_size_ptr = gen_code_ptr - gen_code_buf; | ||
| 2194 | + printf("0x%08lx: code_size = %d\n", (long)pc_start, *gen_code_size_ptr); | ||
| 2195 | + return 0; | ||
| 2196 | +} | ||
| 2197 | + | ||
| 2198 | +CPUX86State *cpu_x86_init(void) | ||
| 2199 | +{ | ||
| 2200 | + CPUX86State *env; | ||
| 2201 | + int i; | ||
| 2202 | + | ||
| 2203 | + env = malloc(sizeof(CPUX86State)); | ||
| 2204 | + if (!env) | ||
| 2205 | + return NULL; | ||
| 2206 | + memset(env, 0, sizeof(CPUX86State)); | ||
| 2207 | + /* basic FPU init */ | ||
| 2208 | + for(i = 0;i < 8; i++) | ||
| 2209 | + env->fptags[i] = 1; | ||
| 2210 | + env->fpuc = 0x37f; | ||
| 2211 | + /* flags setup */ | ||
| 2212 | + env->cc_op = CC_OP_EFLAGS; | ||
| 2213 | + env->df = 1; | ||
| 2214 | + return env; | ||
| 2215 | +} | ||
| 2216 | + | ||
| 2217 | +void cpu_x86_close(CPUX86State *env) | ||
| 2218 | +{ | ||
| 2219 | + free(env); | ||
| 2220 | +} |