Commit 0ecfa9930c7615503ba629a61f7b94a0c3305af5

Authored by bellard
1 parent ba1c6e37

prints hello world


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@17 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
... ... @@ -30,16 +30,19 @@ endif
30 30  
31 31 #########################################################
32 32  
33   -DEFINES+=-D_GNU_SOURCE -DGEMU -DDOSEMU -DNO_TRACE_MSGS
  33 +DEFINES+=-D_GNU_SOURCE
34 34 DEFINES+=-DCONFIG_PREFIX=\"/usr/local\"
35 35 LDSCRIPT=$(ARCH).ld
36 36 LIBS+=-ldl -lm
37 37  
38   -OBJS= i386/fp87.o i386/interp_main.o i386/interp_modrm.o i386/interp_16_32.o \
39   - i386/interp_32_16.o i386/interp_32_32.o i386/emu-utils.o \
40   - i386/dis8086.o i386/emu-ldt.o
  38 +#DEFINES+= -DGEMU -DDOSEMU -DNO_TRACE_MSGS
  39 +#OBJS= i386/fp87.o i386/interp_main.o i386/interp_modrm.o i386/interp_16_32.o \
  40 +# i386/interp_32_16.o i386/interp_32_32.o i386/emu-utils.o \
  41 +# i386/dis8086.o i386/emu-ldt.o
41 42 OBJS+=translate-i386.o op-i386.o
42 43 OBJS+= elfload.o main.o thunk.o syscall.o
  44 +# NOTE: the disassembler code is only needed for debugging
  45 +OBJS+=i386-dis.o dis-buf.o
43 46 SRCS = $(OBJS:.o=.c)
44 47  
45 48 all: gemu
... ...
cpu-i386.h
  1 +/* NOTE: this header is included in op-i386.c where global register
  2 + variable are used. Care must be used when including glibc headers.
  3 + */
1 4 #ifndef CPU_I386_H
2 5 #define CPU_I386_H
3 6  
  7 +#include <setjmp.h>
  8 +
4 9 #define R_EAX 0
5 10 #define R_ECX 1
6 11 #define R_EDX 2
... ... @@ -43,6 +48,27 @@
43 48 #define VM_FLAG 0x20000
44 49 /* AC 0x40000 */
45 50  
  51 +#define EXCP00_DIVZ 1
  52 +#define EXCP01_SSTP 2
  53 +#define EXCP02_NMI 3
  54 +#define EXCP03_INT3 4
  55 +#define EXCP04_INTO 5
  56 +#define EXCP05_BOUND 6
  57 +#define EXCP06_ILLOP 7
  58 +#define EXCP07_PREX 8
  59 +#define EXCP08_DBLE 9
  60 +#define EXCP09_XERR 10
  61 +#define EXCP0A_TSS 11
  62 +#define EXCP0B_NOSEG 12
  63 +#define EXCP0C_STACK 13
  64 +#define EXCP0D_GPF 14
  65 +#define EXCP0E_PAGE 15
  66 +#define EXCP10_COPR 17
  67 +#define EXCP11_ALGN 18
  68 +#define EXCP12_MCHK 19
  69 +
  70 +#define EXCP_SIGNAL 256 /* async signal */
  71 +
46 72 enum {
47 73 CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
48 74 CC_OP_EFLAGS, /* all cc are explicitely computed, CC_SRC = flags */
... ... @@ -89,27 +115,34 @@ typedef struct CPUX86State {
89 115 /* standard registers */
90 116 uint32_t regs[8];
91 117 uint32_t pc; /* cs_case + eip value */
92   -
93   - /* eflags handling */
94 118 uint32_t eflags;
  119 +
  120 + /* emulator internal eflags handling */
95 121 uint32_t cc_src;
96 122 uint32_t cc_dst;
97 123 uint32_t cc_op;
98 124 int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
99   -
  125 +
100 126 /* segments */
101 127 uint8_t *segs_base[6];
102   - uint32_t segs[6];
103 128  
104 129 /* FPU state */
105   - CPU86_LDouble fpregs[8];
106   - uint8_t fptags[8]; /* 0 = valid, 1 = empty */
107 130 unsigned int fpstt; /* top of stack index */
108 131 unsigned int fpus;
109 132 unsigned int fpuc;
  133 + uint8_t fptags[8]; /* 0 = valid, 1 = empty */
  134 + CPU86_LDouble fpregs[8];
  135 +
  136 + /* segments */
  137 + uint32_t segs[6];
110 138  
111 139 /* emulator internal variables */
  140 +
112 141 CPU86_LDouble ft0;
  142 +
  143 + /* exception handling */
  144 + jmp_buf jmp_env;
  145 + int exception_index;
113 146 } CPUX86State;
114 147  
115 148 static inline int ldub(void *ptr)
... ...
linux-user/main.c
... ... @@ -21,10 +21,11 @@
21 21 #include <stdio.h>
22 22 #include <stdarg.h>
23 23 #include <errno.h>
  24 +#include <unistd.h>
24 25  
25 26 #include "gemu.h"
26 27  
27   -#include "i386/hsw_interp.h"
  28 +#include "cpu-i386.h"
28 29  
29 30 unsigned long x86_stack_size;
30 31 unsigned long stktop;
... ... @@ -38,160 +39,8 @@ void gemu_log(const char *fmt, ...)
38 39 va_end(ap);
39 40 }
40 41  
41   -/* virtual x86 CPU stuff */
42   -
43   -extern int invoke_code16(Interp_ENV *, int, int);
44   -extern int invoke_code32(Interp_ENV *, int);
45   -extern char *e_print_cpuemu_regs(ENVPARAMS, int is32);
46   -extern char *e_emu_disasm(ENVPARAMS, unsigned char *org, int is32);
47   -extern void init_npu(void);
48   -
49   -Interp_ENV env_global;
50   -Interp_ENV *envp_global;
51   -
52   -QWORD EMUtime = 0;
53   -
54   -int CEmuStat = 0;
55   -
56   -long instr_count;
57   -
58   -/* who will initialize this? */
59   -unsigned long io_bitmap[IO_BITMAP_SIZE+1];
60   -
61   -/* debug flag, 0=disable 1..9=level */
62   -int d_emu = 0;
63   -
64   -unsigned long CRs[5] =
65   -{
66   - 0x00000013, /* valid bits: 0xe005003f */
67   - 0x00000000, /* invalid */
68   - 0x00000000,
69   - 0x00000000,
70   - 0x00000000
71   -};
72   -
73   -/*
74   - * DR0-3 = linear address of breakpoint 0-3
75   - * DR4=5 = reserved
76   - * DR6 b0-b3 = BP active
77   - * b13 = BD
78   - * b14 = BS
79   - * b15 = BT
80   - * DR7 b0-b1 = G:L bp#0
81   - * b2-b3 = G:L bp#1
82   - * b4-b5 = G:L bp#2
83   - * b6-b7 = G:L bp#3
84   - * b8-b9 = GE:LE
85   - * b13 = GD
86   - * b16-19= LLRW bp#0 LL=00(1),01(2),11(4)
87   - * b20-23= LLRW bp#1 RW=00(x),01(w),11(rw)
88   - * b24-27= LLRW bp#2
89   - * b28-31= LLRW bp#3
90   - */
91   -unsigned long DRs[8] =
92   -{
93   - 0x00000000,
94   - 0x00000000,
95   - 0x00000000,
96   - 0x00000000,
97   - 0xffff1ff0,
98   - 0x00000400,
99   - 0xffff1ff0,
100   - 0x00000400
101   -};
102   -
103   -unsigned long TRs[2] =
104   -{
105   - 0x00000000,
106   - 0x00000000
107   -};
108   -
109   -void FatalAppExit(UINT wAction, LPCSTR lpText)
110   -{
111   - fprintf(stderr, "Fatal error '%s' in CPU\n", lpText);
112   - exit(1);
113   -}
114   -
115   -int e_debug_check(unsigned char *PC)
116   -{
117   - register unsigned long d7 = DRs[7];
118   -
119   - if (d7&0x03) {
120   - if (d7&0x30000) return 0; /* only execute(00) bkp */
121   - if ((long)PC==DRs[0]) {
122   - e_printf("DBRK: DR0 hit at %p\n",PC);
123   - DRs[6] |= 1;
124   - return 1;
125   - }
126   - }
127   - if (d7&0x0c) {
128   - if (d7&0x300000) return 0;
129   - if ((long)PC==DRs[1]) {
130   - e_printf("DBRK: DR1 hit at %p\n",PC);
131   - DRs[6] |= 2;
132   - return 1;
133   - }
134   - }
135   - if (d7&0x30) {
136   - if (d7&0x3000000) return 0;
137   - if ((long)PC==DRs[2]) {
138   - e_printf("DBRK: DR2 hit at %p\n",PC);
139   - DRs[6] |= 4;
140   - return 1;
141   - }
142   - }
143   - if (d7&0xc0) {
144   - if (d7&0x30000000) return 0;
145   - if ((long)PC==DRs[3]) {
146   - e_printf("DBRK: DR3 hit at %p\n",PC);
147   - DRs[6] |= 8;
148   - return 1;
149   - }
150   - }
151   - return 0;
152   -}
153   -
154   -/* Debug stuff */
155   -void logstr(unsigned long mask, const char *fmt,...)
156   -{
157   - va_list ap;
158   -
159   - va_start(ap, fmt);
160   - vfprintf(stderr, fmt, ap);
161   - va_end(ap);
162   -}
163   -
164   -/* unconditional message into debug log and stderr */
165   -#undef error
166   -void error(const char *fmt, ...)
167   -{
168   - va_list ap;
169   -
170   - va_start(ap, fmt);
171   - vfprintf(stderr, fmt, ap);
172   - va_end(ap);
173   - exit(1);
174   -}
175   -
176   -int PortIO(DWORD port, DWORD value, UINT size, BOOL is_write)
177   -{
178   - fprintf(stderr, "IO: %s port=0x%lx value=0x%lx size=%d",
179   - is_write ? "write" : "read", port, value, size);
180   - return value;
181   -}
182   -
183   -void LogProcName(WORD wSel, WORD wOff, WORD wAction)
184   -{
185   -
186   -}
187   -
188   -void INT_handler(int num, void *env)
189   -{
190   - fprintf(stderr, "EM86: int %d\n", num);
191   -}
192   -
193 42 /***********************************************************/
194   -/* new CPU core */
  43 +/* CPUX86 core interface */
195 44  
196 45 void cpu_x86_outb(int addr, int val)
197 46 {
... ... @@ -245,7 +94,7 @@ int main(int argc, char **argv)
245 94 const char *filename;
246 95 struct target_pt_regs regs1, *regs = &regs1;
247 96 struct image_info info1, *info = &info1;
248   - Interp_ENV *env;
  97 + CPUX86State *env;
249 98  
250 99 if (argc <= 1)
251 100 usage();
... ... @@ -277,26 +126,25 @@ int main(int argc, char **argv)
277 126 target_set_brk((char *)info->brk);
278 127 syscall_init();
279 128  
280   - env = &env_global;
281   - envp_global = env;
282   - memset(env, 0, sizeof(Interp_ENV));
283   -
284   - env->rax.e = regs->eax;
285   - env->rbx.e = regs->ebx;
286   - env->rcx.e = regs->ecx;
287   - env->rdx.e = regs->edx;
288   - env->rsi.esi = regs->esi;
289   - env->rdi.edi = regs->edi;
290   - env->rbp.ebp = regs->ebp;
291   - env->rsp.esp = regs->esp;
292   - env->cs.cs = __USER_CS;
293   - env->ds.ds = __USER_DS;
294   - env->es.es = __USER_DS;
295   - env->ss.ss = __USER_DS;
296   - env->fs.fs = __USER_DS;
297   - env->gs.gs = __USER_DS;
298   - env->trans_addr = regs->eip;
  129 + env = cpu_x86_init();
  130 +
  131 + env->regs[R_EAX] = regs->eax;
  132 + env->regs[R_EBX] = regs->ebx;
  133 + env->regs[R_ECX] = regs->ecx;
  134 + env->regs[R_EDX] = regs->edx;
  135 + env->regs[R_ESI] = regs->esi;
  136 + env->regs[R_EDI] = regs->edi;
  137 + env->regs[R_EBP] = regs->ebp;
  138 + env->regs[R_ESP] = regs->esp;
  139 + env->segs[R_CS] = __USER_CS;
  140 + env->segs[R_DS] = __USER_DS;
  141 + env->segs[R_ES] = __USER_DS;
  142 + env->segs[R_SS] = __USER_DS;
  143 + env->segs[R_FS] = __USER_DS;
  144 + env->segs[R_GS] = __USER_DS;
  145 + env->pc = regs->eip;
299 146  
  147 +#if 0
300 148 LDT[__USER_CS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
301 149 LDT[__USER_CS >> 3].dwSelLimit = 0xfffff;
302 150 LDT[__USER_CS >> 3].lpSelBase = NULL;
... ... @@ -304,41 +152,34 @@ int main(int argc, char **argv)
304 152 LDT[__USER_DS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
305 153 LDT[__USER_DS >> 3].dwSelLimit = 0xfffff;
306 154 LDT[__USER_DS >> 3].lpSelBase = NULL;
307   - init_npu();
308   - build_decode_tables();
  155 +#endif
309 156  
310 157 for(;;) {
311 158 int err;
312 159 uint8_t *pc;
313   -
314   - err = invoke_code32(env, -1);
315   - env->trans_addr = env->return_addr;
316   - pc = env->seg_regs[0] + env->trans_addr;
  160 +
  161 + err = cpu_x86_exec(env);
317 162 switch(err) {
318 163 case EXCP0D_GPF:
  164 + pc = (uint8_t *)env->pc;
319 165 if (pc[0] == 0xcd && pc[1] == 0x80) {
320 166 /* syscall */
321   - env->trans_addr += 2;
322   - env->rax.e = do_syscall(env->rax.e,
323   - env->rbx.e,
324   - env->rcx.e,
325   - env->rdx.e,
326   - env->rsi.esi,
327   - env->rdi.edi,
328   - env->rbp.ebp);
  167 + env->pc += 2;
  168 + env->regs[R_EAX] = do_syscall(env->regs[R_EAX],
  169 + env->regs[R_EBX],
  170 + env->regs[R_ECX],
  171 + env->regs[R_EDX],
  172 + env->regs[R_ESI],
  173 + env->regs[R_EDI],
  174 + env->regs[R_EBP]);
329 175 } else {
330 176 goto trap_error;
331 177 }
332 178 break;
333 179 default:
334 180 trap_error:
335   - fprintf(stderr, "GEMU: Unknown error %d, aborting\n", err);
336   -#ifndef NO_TRACE_MSGS
337   - d_emu = 9;
338   - fprintf(stderr, "%s\n%s\n",
339   - e_print_cpuemu_regs(env, 1),
340   - e_emu_disasm(env,pc,1));
341   -#endif
  181 + fprintf(stderr, "0x%08lx: Unknown exception %d, aborting\n",
  182 + (long)env->pc, err);
342 183 abort();
343 184 }
344 185 }
... ...
op-i386.c
... ... @@ -10,11 +10,6 @@ typedef signed long long int64_t;
10 10  
11 11 #define NULL 0
12 12  
13   -typedef struct FILE FILE;
14   -
15   -extern FILE *stderr;
16   -extern int fprintf(FILE *, const char *, ...);
17   -
18 13 #ifdef __i386__
19 14 register int T0 asm("esi");
20 15 register int T1 asm("ebx");
... ... @@ -91,6 +86,7 @@ typedef struct CCTable {
91 86 int (*compute_c)(void); /* return the C flag */
92 87 } CCTable;
93 88  
  89 +/* NOTE: data are not static to force relocation generation by GCC */
94 90 extern CCTable cc_table[];
95 91  
96 92 uint8_t parity_table[256] = {
... ... @@ -191,6 +187,14 @@ static inline int lshift(int x, int n)
191 187 return x >> (-n);
192 188 }
193 189  
  190 +/* exception support */
  191 +/* NOTE: not static to force relocation generation by GCC */
  192 +void raise_exception(int exception_index)
  193 +{
  194 + env->exception_index = exception_index;
  195 + longjmp(env->jmp_env, 1);
  196 +}
  197 +
194 198 /* we define the various pieces of code used by the JIT */
195 199  
196 200 #define REG EAX
... ... @@ -321,7 +325,6 @@ void OPPROTO op_decl_T0_cc(void)
321 325  
322 326 void OPPROTO op_testl_T0_T1_cc(void)
323 327 {
324   - CC_SRC = T0;
325 328 CC_DST = T0 & T1;
326 329 }
327 330  
... ... @@ -555,6 +558,7 @@ void OPPROTO op_stl_T0_A0(void)
555 558 /* jumps */
556 559  
557 560 /* indirect jump */
  561 +
558 562 void OPPROTO op_jmp_T0(void)
559 563 {
560 564 PC = T0;
... ... @@ -565,6 +569,30 @@ void OPPROTO op_jmp_im(void)
565 569 PC = PARAM1;
566 570 }
567 571  
  572 +void OPPROTO op_int_im(void)
  573 +{
  574 + PC = PARAM1;
  575 + raise_exception(EXCP0D_GPF);
  576 +}
  577 +
  578 +void OPPROTO op_int3(void)
  579 +{
  580 + PC = PARAM1;
  581 + raise_exception(EXCP03_INT3);
  582 +}
  583 +
  584 +void OPPROTO op_into(void)
  585 +{
  586 + int eflags;
  587 + eflags = cc_table[CC_OP].compute_all();
  588 + if (eflags & CC_O) {
  589 + PC = PARAM1;
  590 + raise_exception(EXCP04_INTO);
  591 + } else {
  592 + PC = PARAM2;
  593 + }
  594 +}
  595 +
568 596 /* string ops */
569 597  
570 598 #define ldul ldl
... ... @@ -663,17 +691,19 @@ void OPPROTO op_jo_cc(void)
663 691 int eflags;
664 692 eflags = cc_table[CC_OP].compute_all();
665 693 if (eflags & CC_O)
666   - PC += PARAM1;
  694 + PC = PARAM1;
667 695 else
668   - PC += PARAM2;
  696 + PC = PARAM2;
  697 + FORCE_RET();
669 698 }
670 699  
671 700 void OPPROTO op_jb_cc(void)
672 701 {
673 702 if (cc_table[CC_OP].compute_c())
674   - PC += PARAM1;
  703 + PC = PARAM1;
675 704 else
676   - PC += PARAM2;
  705 + PC = PARAM2;
  706 + FORCE_RET();
677 707 }
678 708  
679 709 void OPPROTO op_jz_cc(void)
... ... @@ -681,9 +711,10 @@ void OPPROTO op_jz_cc(void)
681 711 int eflags;
682 712 eflags = cc_table[CC_OP].compute_all();
683 713 if (eflags & CC_Z)
684   - PC += PARAM1;
  714 + PC = PARAM1;
685 715 else
686   - PC += PARAM2;
  716 + PC = PARAM2;
  717 + FORCE_RET();
687 718 }
688 719  
689 720 void OPPROTO op_jbe_cc(void)
... ... @@ -691,9 +722,10 @@ void OPPROTO op_jbe_cc(void)
691 722 int eflags;
692 723 eflags = cc_table[CC_OP].compute_all();
693 724 if (eflags & (CC_Z | CC_C))
694   - PC += PARAM1;
  725 + PC = PARAM1;
695 726 else
696   - PC += PARAM2;
  727 + PC = PARAM2;
  728 + FORCE_RET();
697 729 }
698 730  
699 731 void OPPROTO op_js_cc(void)
... ... @@ -701,9 +733,10 @@ void OPPROTO op_js_cc(void)
701 733 int eflags;
702 734 eflags = cc_table[CC_OP].compute_all();
703 735 if (eflags & CC_S)
704   - PC += PARAM1;
  736 + PC = PARAM1;
705 737 else
706   - PC += PARAM2;
  738 + PC = PARAM2;
  739 + FORCE_RET();
707 740 }
708 741  
709 742 void OPPROTO op_jp_cc(void)
... ... @@ -711,9 +744,10 @@ void OPPROTO op_jp_cc(void)
711 744 int eflags;
712 745 eflags = cc_table[CC_OP].compute_all();
713 746 if (eflags & CC_P)
714   - PC += PARAM1;
  747 + PC = PARAM1;
715 748 else
716   - PC += PARAM2;
  749 + PC = PARAM2;
  750 + FORCE_RET();
717 751 }
718 752  
719 753 void OPPROTO op_jl_cc(void)
... ... @@ -721,9 +755,10 @@ void OPPROTO op_jl_cc(void)
721 755 int eflags;
722 756 eflags = cc_table[CC_OP].compute_all();
723 757 if ((eflags ^ (eflags >> 4)) & 0x80)
724   - PC += PARAM1;
  758 + PC = PARAM1;
725 759 else
726   - PC += PARAM2;
  760 + PC = PARAM2;
  761 + FORCE_RET();
727 762 }
728 763  
729 764 void OPPROTO op_jle_cc(void)
... ... @@ -731,9 +766,10 @@ void OPPROTO op_jle_cc(void)
731 766 int eflags;
732 767 eflags = cc_table[CC_OP].compute_all();
733 768 if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z))
734   - PC += PARAM1;
  769 + PC = PARAM1;
735 770 else
736   - PC += PARAM2;
  771 + PC = PARAM2;
  772 + FORCE_RET();
737 773 }
738 774  
739 775 /* slow set cases (compute x86 flags) */
... ... @@ -1600,14 +1636,13 @@ void OPPROTO op_fcos(void)
1600 1636 /* main execution loop */
1601 1637 uint8_t code_gen_buffer[65536];
1602 1638  
1603   -
1604 1639 int cpu_x86_exec(CPUX86State *env1)
1605 1640 {
1606 1641 int saved_T0, saved_T1, saved_A0;
1607 1642 CPUX86State *saved_env;
1608   - int code_gen_size;
  1643 + int code_gen_size, ret;
1609 1644 void (*gen_func)(void);
1610   -
  1645 +
1611 1646 /* first we save global registers */
1612 1647 saved_T0 = T0;
1613 1648 saved_T1 = T1;
... ... @@ -1615,17 +1650,21 @@ int cpu_x86_exec(CPUX86State *env1)
1615 1650 saved_env = env;
1616 1651 env = env1;
1617 1652  
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();
  1653 + /* prepare setjmp context for exception handling */
  1654 + if (setjmp(env->jmp_env) == 0) {
  1655 + for(;;) {
  1656 + cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc);
  1657 + /* execute the generated code */
  1658 + gen_func = (void *)code_gen_buffer;
  1659 + gen_func();
  1660 + }
1623 1661 }
1624   -
  1662 + ret = env->exception_index;
  1663 +
1625 1664 /* restore global registers */
1626 1665 T0 = saved_T0;
1627 1666 T1 = saved_T1;
1628 1667 A0 = saved_A0;
1629 1668 env = saved_env;
1630   - return 0;
  1669 + return ret;
1631 1670 }
... ...
ops_template.h
... ... @@ -149,18 +149,18 @@ void OPPROTO glue(op_jb_sub, SUFFIX)(void)
149 149 src2 = CC_SRC - CC_DST;
150 150  
151 151 if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
152   - PC += PARAM1;
  152 + PC = PARAM1;
153 153 else
154   - PC += PARAM2;
  154 + PC = PARAM2;
155 155 FORCE_RET();
156 156 }
157 157  
158 158 void OPPROTO glue(op_jz_sub, SUFFIX)(void)
159 159 {
160 160 if ((DATA_TYPE)CC_DST != 0)
161   - PC += PARAM1;
  161 + PC = PARAM1;
162 162 else
163   - PC += PARAM2;
  163 + PC = PARAM2;
164 164 FORCE_RET();
165 165 }
166 166  
... ... @@ -171,18 +171,18 @@ void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
171 171 src2 = CC_SRC - CC_DST;
172 172  
173 173 if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
174   - PC += PARAM1;
  174 + PC = PARAM1;
175 175 else
176   - PC += PARAM2;
  176 + PC = PARAM2;
177 177 FORCE_RET();
178 178 }
179 179  
180 180 void OPPROTO glue(op_js_sub, SUFFIX)(void)
181 181 {
182 182 if (CC_DST & SIGN_MASK)
183   - PC += PARAM1;
  183 + PC = PARAM1;
184 184 else
185   - PC += PARAM2;
  185 + PC = PARAM2;
186 186 FORCE_RET();
187 187 }
188 188  
... ... @@ -193,9 +193,9 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(void)
193 193 src2 = CC_SRC - CC_DST;
194 194  
195 195 if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
196   - PC += PARAM1;
  196 + PC = PARAM1;
197 197 else
198   - PC += PARAM2;
  198 + PC = PARAM2;
199 199 FORCE_RET();
200 200 }
201 201  
... ... @@ -206,9 +206,9 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(void)
206 206 src2 = CC_SRC - CC_DST;
207 207  
208 208 if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
209   - PC += PARAM1;
  209 + PC = PARAM1;
210 210 else
211   - PC += PARAM2;
  211 + PC = PARAM2;
212 212 FORCE_RET();
213 213 }
214 214  
... ...
translate-i386.c
... ... @@ -5,12 +5,24 @@
5 5 #include <inttypes.h>
6 6 #include <assert.h>
7 7  
  8 +/* dump all code */
  9 +#define DEBUG_DISAS
  10 +#define DEBUG_LOGFILE "/tmp/gemu.log"
  11 +
  12 +#ifdef DEBUG_DISAS
  13 +#include "dis-asm.h"
  14 +#endif
  15 +
8 16 #define IN_OP_I386
9 17 #include "cpu-i386.h"
10 18  
11 19 static uint8_t *gen_code_ptr;
12 20 int __op_param1, __op_param2, __op_param3;
13 21  
  22 +#ifdef DEBUG_DISAS
  23 +static FILE *logfile = NULL;
  24 +#endif
  25 +
14 26 /* supress that */
15 27 static void error(const char *fmt, ...)
16 28 {
... ... @@ -704,6 +716,9 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
704 716 int reg1, reg2, opreg;
705 717 int mod, rm, code;
706 718  
  719 +#ifdef DEBUG_DISAS
  720 + fprintf(logfile, "modrm=0x%x\n", modrm);
  721 +#endif
707 722 mod = (modrm >> 6) & 3;
708 723 rm = modrm & 7;
709 724  
... ... @@ -716,6 +731,9 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
716 731 if (base == 4) {
717 732 havesib = 1;
718 733 code = ldub(s->pc++);
  734 +#ifdef DEBUG_DISAS
  735 + fprintf(logfile, "sib=0x%x\n", code);
  736 +#endif
719 737 scale = (code >> 6) & 3;
720 738 index = (code >> 3) & 7;
721 739 base = code & 7;
... ... @@ -762,6 +780,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
762 780 } else if (scale == 0 && disp == 0) {
763 781 gen_op_movl_A0_reg[reg1]();
764 782 } else {
  783 + gen_op_movl_A0_im(disp);
765 784 gen_op_addl_A0_reg_sN[scale][reg1]();
766 785 }
767 786 } else {
... ... @@ -953,8 +972,10 @@ static void gen_setcc(DisasContext *s, int b)
953 972 }
954 973 }
955 974  
956   -/* return the size of the intruction. Return -1 if no insn found */
957   -int disas_insn(DisasContext *s, uint8_t *pc_start)
  975 +/* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
  976 + is set to true if the instruction sets the PC (last instruction of
  977 + a basic block) */
  978 +long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
958 979 {
959 980 int b, prefixes, aflag, dflag;
960 981 int shift, ot;
... ... @@ -967,6 +988,9 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
967 988 // cur_pc = s->pc; /* for insn generation */
968 989 next_byte:
969 990 b = ldub(s->pc);
  991 +#ifdef DEBUG_DISAS
  992 + fprintf(logfile, "ib=0x%02x\n", b);
  993 +#endif
970 994 if (b < 0)
971 995 return -1;
972 996 s->pc++;
... ... @@ -1195,6 +1219,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
1195 1219 gen_op_mull_EAX_T0();
1196 1220 break;
1197 1221 }
  1222 + s->cc_op = CC_OP_MUL;
1198 1223 break;
1199 1224 case 5: /* imul */
1200 1225 switch(ot) {
... ... @@ -1209,6 +1234,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
1209 1234 gen_op_imull_EAX_T0();
1210 1235 break;
1211 1236 }
  1237 + s->cc_op = CC_OP_MUL;
1212 1238 break;
1213 1239 case 6: /* div */
1214 1240 switch(ot) {
... ... @@ -1281,9 +1307,11 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
1281 1307 gen_op_movl_T1_im((long)s->pc);
1282 1308 gen_op_pushl_T1();
1283 1309 gen_op_jmp_T0();
  1310 + *is_jmp_ptr = 1;
1284 1311 break;
1285 1312 case 4: /* jmp Ev */
1286 1313 gen_op_jmp_T0();
  1314 + *is_jmp_ptr = 1;
1287 1315 break;
1288 1316 case 6: /* push Ev */
1289 1317 gen_op_pushl_T0();
... ... @@ -1362,6 +1390,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
1362 1390 op_imulw_T0_T1();
1363 1391 }
1364 1392 gen_op_mov_reg_T0[ot][reg]();
  1393 + s->cc_op = CC_OP_MUL;
1365 1394 break;
1366 1395  
1367 1396 /**************************/
... ... @@ -1418,10 +1447,14 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
1418 1447 ot = dflag ? OT_LONG : OT_WORD;
1419 1448 modrm = ldub(s->pc++);
1420 1449 mod = (modrm >> 6) & 3;
1421   -
  1450 + if (mod != 3)
  1451 + gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1422 1452 val = insn_get(s, ot);
1423 1453 gen_op_movl_T0_im(val);
1424   - gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
  1454 + if (mod != 3)
  1455 + gen_op_st_T0_A0[ot]();
  1456 + else
  1457 + gen_op_mov_reg_T0[ot][modrm & 7]();
1425 1458 break;
1426 1459 case 0x8a:
1427 1460 case 0x8b: /* mov Ev, Gv */
... ... @@ -2068,10 +2101,12 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
2068 2101 gen_op_popl_T0();
2069 2102 gen_op_addl_ESP_im(val);
2070 2103 gen_op_jmp_T0();
  2104 + *is_jmp_ptr = 1;
2071 2105 break;
2072 2106 case 0xc3: /* ret */
2073 2107 gen_op_popl_T0();
2074 2108 gen_op_jmp_T0();
  2109 + *is_jmp_ptr = 1;
2075 2110 break;
2076 2111 case 0xe8: /* call */
2077 2112 val = insn_get(s, OT_LONG);
... ... @@ -2079,16 +2114,19 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
2079 2114 gen_op_movl_T1_im((long)s->pc);
2080 2115 gen_op_pushl_T1();
2081 2116 gen_op_jmp_im(val);
  2117 + *is_jmp_ptr = 1;
2082 2118 break;
2083 2119 case 0xe9: /* jmp */
2084 2120 val = insn_get(s, OT_LONG);
2085 2121 val += (long)s->pc;
2086 2122 gen_op_jmp_im(val);
  2123 + *is_jmp_ptr = 1;
2087 2124 break;
2088 2125 case 0xeb: /* jmp Jb */
2089 2126 val = (int8_t)insn_get(s, OT_BYTE);
2090 2127 val += (long)s->pc;
2091 2128 gen_op_jmp_im(val);
  2129 + *is_jmp_ptr = 1;
2092 2130 break;
2093 2131 case 0x70 ... 0x7f: /* jcc Jb */
2094 2132 val = (int8_t)insn_get(s, OT_BYTE);
... ... @@ -2103,6 +2141,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
2103 2141 val += (long)s->pc; /* XXX: fix 16 bit wrap */
2104 2142 do_jcc:
2105 2143 gen_jcc(s, b, val);
  2144 + *is_jmp_ptr = 1;
2106 2145 break;
2107 2146  
2108 2147 case 0x190 ... 0x19f:
... ... @@ -2164,8 +2203,23 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
2164 2203 /* misc */
2165 2204 case 0x90: /* nop */
2166 2205 break;
2167   -
2168   -#if 0
  2206 + case 0xcc: /* int3 */
  2207 + gen_op_int3((long)pc_start);
  2208 + *is_jmp_ptr = 1;
  2209 + break;
  2210 + case 0xcd: /* int N */
  2211 + val = ldub(s->pc++);
  2212 + /* XXX: currently we ignore the interrupt number */
  2213 + gen_op_int_im((long)pc_start);
  2214 + *is_jmp_ptr = 1;
  2215 + break;
  2216 + case 0xce: /* into */
  2217 + if (s->cc_op != CC_OP_DYNAMIC)
  2218 + gen_op_set_cc_op(s->cc_op);
  2219 + gen_op_into((long)pc_start, (long)s->pc);
  2220 + *is_jmp_ptr = 1;
  2221 + break;
  2222 +#if 0
2169 2223 case 0x1a2: /* cpuid */
2170 2224 gen_insn0(OP_ASM);
2171 2225 break;
... ... @@ -2182,16 +2236,78 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr,
2182 2236 uint8_t *pc_start)
2183 2237 {
2184 2238 DisasContext dc1, *dc = &dc1;
  2239 + int is_jmp;
2185 2240 long ret;
  2241 +#ifdef DEBUG_DISAS
  2242 + struct disassemble_info disasm_info;
  2243 +#endif
  2244 +
2186 2245 dc->cc_op = CC_OP_DYNAMIC;
2187 2246 gen_code_ptr = gen_code_buf;
2188 2247 gen_start();
2189   - ret = disas_insn(dc, pc_start);
  2248 +
  2249 +#ifdef DEBUG_DISAS
  2250 + if (!logfile) {
  2251 + logfile = fopen(DEBUG_LOGFILE, "w");
  2252 + if (!logfile) {
  2253 + perror(DEBUG_LOGFILE);
  2254 + exit(1);
  2255 + }
  2256 + setvbuf(logfile, NULL, _IOLBF, 0);
  2257 + }
  2258 +
  2259 + INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
  2260 + disasm_info.buffer = pc_start;
  2261 + disasm_info.buffer_vma = (unsigned long)pc_start;
  2262 + disasm_info.buffer_length = 15;
  2263 +#if 0
  2264 + disasm_info.flavour = bfd_get_flavour (abfd);
  2265 + disasm_info.arch = bfd_get_arch (abfd);
  2266 + disasm_info.mach = bfd_get_mach (abfd);
  2267 +#endif
  2268 +#ifdef WORDS_BIGENDIAN
  2269 + disasm_info.endian = BFD_ENDIAN_BIG;
  2270 +#else
  2271 + disasm_info.endian = BFD_ENDIAN_LITTLE;
  2272 +#endif
  2273 + fprintf(logfile, "IN:\n");
  2274 + fprintf(logfile, "0x%08lx: ", (long)pc_start);
  2275 + print_insn_i386((unsigned long)pc_start, &disasm_info);
  2276 + fprintf(logfile, "\n\n");
  2277 +#endif
  2278 + is_jmp = 0;
  2279 + ret = disas_insn(dc, pc_start, &is_jmp);
2190 2280 if (ret == -1)
2191 2281 error("unknown instruction at PC=0x%x", pc_start);
  2282 + /* we must store the eflags state if it is not already done */
  2283 + if (dc->cc_op != CC_OP_DYNAMIC)
  2284 + gen_op_set_cc_op(dc->cc_op);
  2285 + if (!is_jmp) {
  2286 + /* we add an additionnal jmp to update the simulated PC */
  2287 + gen_op_jmp_im(ret);
  2288 + }
2192 2289 gen_end();
2193 2290 *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);
  2291 +
  2292 +#ifdef DEBUG_DISAS
  2293 + {
  2294 + uint8_t *pc;
  2295 + int count;
  2296 +
  2297 + pc = gen_code_buf;
  2298 + disasm_info.buffer = pc;
  2299 + disasm_info.buffer_vma = (unsigned long)pc;
  2300 + disasm_info.buffer_length = *gen_code_size_ptr;
  2301 + fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
  2302 + while (pc < gen_code_ptr) {
  2303 + fprintf(logfile, "0x%08lx: ", (long)pc);
  2304 + count = print_insn_i386((unsigned long)pc, &disasm_info);
  2305 + fprintf(logfile, "\n");
  2306 + pc += count;
  2307 + }
  2308 + fprintf(logfile, "\n");
  2309 + }
  2310 +#endif
2195 2311 return 0;
2196 2312 }
2197 2313  
... ...