Commit dab2ed991a49678fbd4d45ff1b328340a77057df

Authored by bellard
1 parent e5918247

better 16 bit code support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@38 c046a42c-6fe2-441c-8c8c-71466251a162
  1 +- overrides/16bit for string ops
1 - optimize translated cache chaining (DLL PLT-like system) 2 - optimize translated cache chaining (DLL PLT-like system)
2 - 64 bit syscalls 3 - 64 bit syscalls
3 - signals 4 - signals
cpu-i386.h
@@ -141,7 +141,7 @@ typedef struct SegmentDescriptorTable { @@ -141,7 +141,7 @@ typedef struct SegmentDescriptorTable {
141 typedef struct CPUX86State { 141 typedef struct CPUX86State {
142 /* standard registers */ 142 /* standard registers */
143 uint32_t regs[8]; 143 uint32_t regs[8];
144 - uint32_t pc; /* cs_case + eip value */ 144 + uint32_t eip;
145 uint32_t eflags; 145 uint32_t eflags;
146 146
147 /* emulator internal eflags handling */ 147 /* emulator internal eflags handling */
@@ -392,10 +392,12 @@ void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector); @@ -392,10 +392,12 @@ void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
392 392
393 #define GEN_FLAG_CODE32_SHIFT 0 393 #define GEN_FLAG_CODE32_SHIFT 0
394 #define GEN_FLAG_ADDSEG_SHIFT 1 394 #define GEN_FLAG_ADDSEG_SHIFT 1
395 -#define GEN_FLAG_ST_SHIFT 2 395 +#define GEN_FLAG_SS32_SHIFT 2
  396 +#define GEN_FLAG_ST_SHIFT 3
  397 +
396 int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, 398 int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
397 - int *gen_code_size_ptr, uint8_t *pc_start,  
398 - int flags); 399 + int *gen_code_size_ptr,
  400 + uint8_t *pc_start, uint8_t *cs_base, int flags);
399 void cpu_x86_tblocks_init(void); 401 void cpu_x86_tblocks_init(void);
400 402
401 #endif /* CPU_I386_H */ 403 #endif /* CPU_I386_H */
exec-i386.c
@@ -38,7 +38,8 @@ @@ -38,7 +38,8 @@
38 #define CODE_GEN_HASH_SIZE (1 << CODE_GEN_HASH_BITS) 38 #define CODE_GEN_HASH_SIZE (1 << CODE_GEN_HASH_BITS)
39 39
40 typedef struct TranslationBlock { 40 typedef struct TranslationBlock {
41 - unsigned long pc; /* simulated PC corresponding to this block */ 41 + unsigned long pc; /* simulated PC corresponding to this block (EIP + CS base) */
  42 + unsigned long cs_base; /* CS base for this block */
42 unsigned int flags; /* flags defining in which context the code was generated */ 43 unsigned int flags; /* flags defining in which context the code was generated */
43 uint8_t *tc_ptr; /* pointer to the translated code */ 44 uint8_t *tc_ptr; /* pointer to the translated code */
44 struct TranslationBlock *hash_next; /* next matching block */ 45 struct TranslationBlock *hash_next; /* next matching block */
@@ -140,6 +141,7 @@ static void tb_flush(void) @@ -140,6 +141,7 @@ static void tb_flush(void)
140 /* find a translation block in the translation cache. If not found, 141 /* find a translation block in the translation cache. If not found,
141 allocate a new one */ 142 allocate a new one */
142 static inline TranslationBlock *tb_find_and_alloc(unsigned long pc, 143 static inline TranslationBlock *tb_find_and_alloc(unsigned long pc,
  144 + unsigned long cs_base,
143 unsigned int flags) 145 unsigned int flags)
144 { 146 {
145 TranslationBlock **ptb, *tb; 147 TranslationBlock **ptb, *tb;
@@ -151,7 +153,7 @@ static inline TranslationBlock *tb_find_and_alloc(unsigned long pc, @@ -151,7 +153,7 @@ static inline TranslationBlock *tb_find_and_alloc(unsigned long pc,
151 tb = *ptb; 153 tb = *ptb;
152 if (!tb) 154 if (!tb)
153 break; 155 break;
154 - if (tb->pc == pc && tb->flags == flags) 156 + if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags)
155 return tb; 157 return tb;
156 ptb = &tb->hash_next; 158 ptb = &tb->hash_next;
157 } 159 }
@@ -161,6 +163,7 @@ static inline TranslationBlock *tb_find_and_alloc(unsigned long pc, @@ -161,6 +163,7 @@ static inline TranslationBlock *tb_find_and_alloc(unsigned long pc,
161 tb = &tbs[nb_tbs++]; 163 tb = &tbs[nb_tbs++];
162 *ptb = tb; 164 *ptb = tb;
163 tb->pc = pc; 165 tb->pc = pc;
  166 + tb->cs_base = cs_base;
164 tb->flags = flags; 167 tb->flags = flags;
165 tb->tc_ptr = NULL; 168 tb->tc_ptr = NULL;
166 tb->hash_next = NULL; 169 tb->hash_next = NULL;
@@ -198,7 +201,7 @@ int cpu_x86_exec(CPUX86State *env1) @@ -198,7 +201,7 @@ int cpu_x86_exec(CPUX86State *env1)
198 int code_gen_size, ret; 201 int code_gen_size, ret;
199 void (*gen_func)(void); 202 void (*gen_func)(void);
200 TranslationBlock *tb; 203 TranslationBlock *tb;
201 - uint8_t *tc_ptr; 204 + uint8_t *tc_ptr, *cs_base, *pc;
202 unsigned int flags; 205 unsigned int flags;
203 206
204 /* first we save global registers */ 207 /* first we save global registers */
@@ -251,17 +254,21 @@ int cpu_x86_exec(CPUX86State *env1) @@ -251,17 +254,21 @@ int cpu_x86_exec(CPUX86State *env1)
251 /* we compute the CPU state. We assume it will not 254 /* we compute the CPU state. We assume it will not
252 change during the whole generated block. */ 255 change during the whole generated block. */
253 flags = env->seg_cache[R_CS].seg_32bit << GEN_FLAG_CODE32_SHIFT; 256 flags = env->seg_cache[R_CS].seg_32bit << GEN_FLAG_CODE32_SHIFT;
  257 + flags |= env->seg_cache[R_SS].seg_32bit << GEN_FLAG_SS32_SHIFT;
254 flags |= (((unsigned long)env->seg_cache[R_DS].base | 258 flags |= (((unsigned long)env->seg_cache[R_DS].base |
255 (unsigned long)env->seg_cache[R_ES].base | 259 (unsigned long)env->seg_cache[R_ES].base |
256 (unsigned long)env->seg_cache[R_SS].base) != 0) << 260 (unsigned long)env->seg_cache[R_SS].base) != 0) <<
257 GEN_FLAG_ADDSEG_SHIFT; 261 GEN_FLAG_ADDSEG_SHIFT;
258 - tb = tb_find_and_alloc((unsigned long)env->pc, flags); 262 + cs_base = env->seg_cache[R_CS].base;
  263 + pc = cs_base + env->eip;
  264 + tb = tb_find_and_alloc((unsigned long)pc, (unsigned long)cs_base,
  265 + flags);
259 tc_ptr = tb->tc_ptr; 266 tc_ptr = tb->tc_ptr;
260 if (!tb->tc_ptr) { 267 if (!tb->tc_ptr) {
261 /* if no translated code available, then translate it now */ 268 /* if no translated code available, then translate it now */
262 tc_ptr = code_gen_ptr; 269 tc_ptr = code_gen_ptr;
263 cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE, 270 cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE,
264 - &code_gen_size, (uint8_t *)env->pc, flags); 271 + &code_gen_size, pc, cs_base, flags);
265 tb->tc_ptr = tc_ptr; 272 tb->tc_ptr = tc_ptr;
266 code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); 273 code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
267 } 274 }
exec-i386.h
@@ -111,7 +111,7 @@ register struct CPUX86State *env asm(&quot;l3&quot;); @@ -111,7 +111,7 @@ register struct CPUX86State *env asm(&quot;l3&quot;);
111 #ifndef reg_EDI 111 #ifndef reg_EDI
112 #define EDI (env->regs[R_EDI]) 112 #define EDI (env->regs[R_EDI])
113 #endif 113 #endif
114 -#define PC (env->pc) 114 +#define EIP (env->eip)
115 #define DF (env->df) 115 #define DF (env->df)
116 116
117 #define CC_SRC (env->cc_src) 117 #define CC_SRC (env->cc_src)
linux-user/main.c
@@ -179,7 +179,7 @@ int main(int argc, char **argv) @@ -179,7 +179,7 @@ int main(int argc, char **argv)
179 env->regs[R_EDI] = regs->edi; 179 env->regs[R_EDI] = regs->edi;
180 env->regs[R_EBP] = regs->ebp; 180 env->regs[R_EBP] = regs->ebp;
181 env->regs[R_ESP] = regs->esp; 181 env->regs[R_ESP] = regs->esp;
182 - env->pc = regs->eip; 182 + env->eip = regs->eip;
183 183
184 /* linux segment setup */ 184 /* linux segment setup */
185 env->gdt.base = (void *)gdt_table; 185 env->gdt.base = (void *)gdt_table;
@@ -198,12 +198,12 @@ int main(int argc, char **argv) @@ -198,12 +198,12 @@ int main(int argc, char **argv)
198 uint8_t *pc; 198 uint8_t *pc;
199 199
200 err = cpu_x86_exec(env); 200 err = cpu_x86_exec(env);
  201 + pc = env->seg_cache[R_CS].base + env->eip;
201 switch(err) { 202 switch(err) {
202 case EXCP0D_GPF: 203 case EXCP0D_GPF:
203 - pc = (uint8_t *)env->pc;  
204 if (pc[0] == 0xcd && pc[1] == 0x80) { 204 if (pc[0] == 0xcd && pc[1] == 0x80) {
205 /* syscall */ 205 /* syscall */
206 - env->pc += 2; 206 + env->eip += 2;
207 env->regs[R_EAX] = do_syscall(env, 207 env->regs[R_EAX] = do_syscall(env,
208 env->regs[R_EAX], 208 env->regs[R_EAX],
209 env->regs[R_EBX], 209 env->regs[R_EBX],
@@ -219,7 +219,7 @@ int main(int argc, char **argv) @@ -219,7 +219,7 @@ int main(int argc, char **argv)
219 default: 219 default:
220 trap_error: 220 trap_error:
221 fprintf(stderr, "0x%08lx: Unknown exception %d, aborting\n", 221 fprintf(stderr, "0x%08lx: Unknown exception %d, aborting\n",
222 - (long)env->pc, err); 222 + (long)pc, err);
223 abort(); 223 abort();
224 } 224 }
225 } 225 }
linux-user/syscall.c
@@ -53,6 +53,7 @@ @@ -53,6 +53,7 @@
53 #include <linux/cdrom.h> 53 #include <linux/cdrom.h>
54 #include <linux/hdreg.h> 54 #include <linux/hdreg.h>
55 #include <linux/soundcard.h> 55 #include <linux/soundcard.h>
  56 +#include <linux/dirent.h>
56 57
57 #include "gemu.h" 58 #include "gemu.h"
58 59
@@ -63,13 +64,6 @@ @@ -63,13 +64,6 @@
63 #define PAGE_MASK ~(PAGE_SIZE - 1) 64 #define PAGE_MASK ~(PAGE_SIZE - 1)
64 #endif 65 #endif
65 66
66 -struct dirent {  
67 - long d_ino;  
68 - long d_off;  
69 - unsigned short d_reclen;  
70 - char d_name[256]; /* We must not include limits.h! */  
71 -};  
72 -  
73 //#include <linux/msdos_fs.h> 67 //#include <linux/msdos_fs.h>
74 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) 68 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
75 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) 69 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
@@ -86,6 +80,7 @@ struct dirent { @@ -86,6 +80,7 @@ struct dirent {
86 #define __NR_sys_statfs __NR_statfs 80 #define __NR_sys_statfs __NR_statfs
87 #define __NR_sys_fstatfs __NR_fstatfs 81 #define __NR_sys_fstatfs __NR_fstatfs
88 #define __NR_sys_getdents __NR_getdents 82 #define __NR_sys_getdents __NR_getdents
  83 +#define __NR_sys_getdents64 __NR_getdents64
89 84
90 #ifdef __NR_gettid 85 #ifdef __NR_gettid
91 _syscall0(int, gettid) 86 _syscall0(int, gettid)
@@ -97,6 +92,7 @@ static int gettid(void) { @@ -97,6 +92,7 @@ static int gettid(void) {
97 _syscall1(int,sys_uname,struct new_utsname *,buf) 92 _syscall1(int,sys_uname,struct new_utsname *,buf)
98 _syscall2(int,sys_getcwd1,char *,buf,size_t,size) 93 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
99 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count); 94 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
  95 +_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
100 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, 96 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
101 loff_t *, res, uint, wh); 97 loff_t *, res, uint, wh);
102 _syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf) 98 _syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf)
@@ -1005,7 +1001,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -1005,7 +1001,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1005 ret = get_errno(setsid()); 1001 ret = get_errno(setsid());
1006 break; 1002 break;
1007 case TARGET_NR_sigaction: 1003 case TARGET_NR_sigaction:
1008 -#if 0 1004 +#if 1
1009 { 1005 {
1010 ret = 0; 1006 ret = 0;
1011 } 1007 }
@@ -1336,6 +1332,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -1336,6 +1332,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1336 { 1332 {
1337 struct dirent *dirp = (void *)arg2; 1333 struct dirent *dirp = (void *)arg2;
1338 long count = arg3; 1334 long count = arg3;
  1335 +
1339 ret = get_errno(sys_getdents(arg1, dirp, count)); 1336 ret = get_errno(sys_getdents(arg1, dirp, count));
1340 if (!is_error(ret)) { 1337 if (!is_error(ret)) {
1341 struct dirent *de; 1338 struct dirent *de;
@@ -1355,6 +1352,29 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -1355,6 +1352,29 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1355 } 1352 }
1356 } 1353 }
1357 break; 1354 break;
  1355 + case TARGET_NR_getdents64:
  1356 + {
  1357 + struct dirent64 *dirp = (void *)arg2;
  1358 + long count = arg3;
  1359 + ret = get_errno(sys_getdents64(arg1, dirp, count));
  1360 + if (!is_error(ret)) {
  1361 + struct dirent64 *de;
  1362 + int len = ret;
  1363 + int reclen;
  1364 + de = dirp;
  1365 + while (len > 0) {
  1366 + reclen = tswap16(de->d_reclen);
  1367 + if (reclen > len)
  1368 + break;
  1369 + de->d_reclen = reclen;
  1370 + tswap64s(&de->d_ino);
  1371 + tswap64s(&de->d_off);
  1372 + de = (struct dirent64 *)((char *)de + reclen);
  1373 + len -= reclen;
  1374 + }
  1375 + }
  1376 + }
  1377 + break;
1358 case TARGET_NR__newselect: 1378 case TARGET_NR__newselect:
1359 ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 1379 ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4,
1360 (void *)arg5); 1380 (void *)arg5);
@@ -1519,7 +1539,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -1519,7 +1539,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1519 case TARGET_NR_pivot_root: 1539 case TARGET_NR_pivot_root:
1520 case TARGET_NR_mincore: 1540 case TARGET_NR_mincore:
1521 case TARGET_NR_madvise: 1541 case TARGET_NR_madvise:
1522 - case TARGET_NR_getdents64:  
1523 goto unimplemented; 1542 goto unimplemented;
1524 #if TARGET_LONG_BITS == 32 1543 #if TARGET_LONG_BITS == 32
1525 case TARGET_NR_fcntl64: 1544 case TARGET_NR_fcntl64:
linux-user/syscall_defs.h
@@ -75,6 +75,22 @@ struct kernel_statfs { @@ -75,6 +75,22 @@ struct kernel_statfs {
75 int f_spare[6]; 75 int f_spare[6];
76 }; 76 };
77 77
  78 +struct target_dirent {
  79 + target_long d_ino;
  80 + target_long d_off;
  81 + unsigned short d_reclen;
  82 + char d_name[256]; /* We must not include limits.h! */
  83 +};
  84 +
  85 +struct target_dirent64 {
  86 + uint64_t d_ino;
  87 + int64_t d_off;
  88 + unsigned short d_reclen;
  89 + unsigned char d_type;
  90 + char d_name[256];
  91 +};
  92 +
  93 +
78 /* mostly generic signal stuff */ 94 /* mostly generic signal stuff */
79 #define TARGET_SIG_DFL ((target_long)0) /* default signal handling */ 95 #define TARGET_SIG_DFL ((target_long)0) /* default signal handling */
80 #define TARGET_SIG_IGN ((target_long)1) /* ignore signal */ 96 #define TARGET_SIG_IGN ((target_long)1) /* ignore signal */
op-i386.c
@@ -464,18 +464,43 @@ void OPPROTO op_idivl_EAX_T0(void) @@ -464,18 +464,43 @@ void OPPROTO op_idivl_EAX_T0(void)
464 EDX = r; 464 EDX = r;
465 } 465 }
466 466
467 -/* constant load */ 467 +/* constant load & misc op */
468 468
469 void OPPROTO op_movl_T0_im(void) 469 void OPPROTO op_movl_T0_im(void)
470 { 470 {
471 T0 = PARAM1; 471 T0 = PARAM1;
472 } 472 }
473 473
  474 +void OPPROTO op_addl_T0_im(void)
  475 +{
  476 + T0 += PARAM1;
  477 +}
  478 +
  479 +void OPPROTO op_andl_T0_ffff(void)
  480 +{
  481 + T0 = T0 & 0xffff;
  482 +}
  483 +
  484 +void OPPROTO op_movl_T0_T1(void)
  485 +{
  486 + T0 = T1;
  487 +}
  488 +
474 void OPPROTO op_movl_T1_im(void) 489 void OPPROTO op_movl_T1_im(void)
475 { 490 {
476 T1 = PARAM1; 491 T1 = PARAM1;
477 } 492 }
478 493
  494 +void OPPROTO op_addl_T1_im(void)
  495 +{
  496 + T1 += PARAM1;
  497 +}
  498 +
  499 +void OPPROTO op_movl_T1_A0(void)
  500 +{
  501 + T1 = A0;
  502 +}
  503 +
479 void OPPROTO op_movl_A0_im(void) 504 void OPPROTO op_movl_A0_im(void)
480 { 505 {
481 A0 = PARAM1; 506 A0 = PARAM1;
@@ -574,23 +599,23 @@ void OPPROTO op_add_bitl_A0_T1(void) @@ -574,23 +599,23 @@ void OPPROTO op_add_bitl_A0_T1(void)
574 599
575 void OPPROTO op_jmp_T0(void) 600 void OPPROTO op_jmp_T0(void)
576 { 601 {
577 - PC = T0; 602 + EIP = T0;
578 } 603 }
579 604
580 void OPPROTO op_jmp_im(void) 605 void OPPROTO op_jmp_im(void)
581 { 606 {
582 - PC = PARAM1; 607 + EIP = PARAM1;
583 } 608 }
584 609
585 void OPPROTO op_int_im(void) 610 void OPPROTO op_int_im(void)
586 { 611 {
587 - PC = PARAM1; 612 + EIP = PARAM1;
588 raise_exception(EXCP0D_GPF); 613 raise_exception(EXCP0D_GPF);
589 } 614 }
590 615
591 void OPPROTO op_int3(void) 616 void OPPROTO op_int3(void)
592 { 617 {
593 - PC = PARAM1; 618 + EIP = PARAM1;
594 raise_exception(EXCP03_INT3); 619 raise_exception(EXCP03_INT3);
595 } 620 }
596 621
@@ -599,10 +624,10 @@ void OPPROTO op_into(void) @@ -599,10 +624,10 @@ void OPPROTO op_into(void)
599 int eflags; 624 int eflags;
600 eflags = cc_table[CC_OP].compute_all(); 625 eflags = cc_table[CC_OP].compute_all();
601 if (eflags & CC_O) { 626 if (eflags & CC_O) {
602 - PC = PARAM1; 627 + EIP = PARAM1;
603 raise_exception(EXCP04_INTO); 628 raise_exception(EXCP04_INTO);
604 } else { 629 } else {
605 - PC = PARAM2; 630 + EIP = PARAM2;
606 } 631 }
607 } 632 }
608 633
@@ -665,7 +690,6 @@ void OPPROTO op_movswl_DX_AX(void) @@ -665,7 +690,6 @@ void OPPROTO op_movswl_DX_AX(void)
665 } 690 }
666 691
667 /* push/pop */ 692 /* push/pop */
668 -/* XXX: add 16 bit operand/16 bit seg variants */  
669 693
670 void op_pushl_T0(void) 694 void op_pushl_T0(void)
671 { 695 {
@@ -676,107 +700,110 @@ void op_pushl_T0(void) @@ -676,107 +700,110 @@ void op_pushl_T0(void)
676 ESP = offset; 700 ESP = offset;
677 } 701 }
678 702
679 -void op_pushl_T1(void) 703 +void op_pushw_T0(void)
  704 +{
  705 + uint32_t offset;
  706 + offset = ESP - 2;
  707 + stw((void *)offset, T0);
  708 + /* modify ESP after to handle exceptions correctly */
  709 + ESP = offset;
  710 +}
  711 +
  712 +void op_pushl_ss32_T0(void)
680 { 713 {
681 uint32_t offset; 714 uint32_t offset;
682 offset = ESP - 4; 715 offset = ESP - 4;
683 - stl((void *)offset, T1); 716 + stl(env->seg_cache[R_SS].base + offset, T0);
684 /* modify ESP after to handle exceptions correctly */ 717 /* modify ESP after to handle exceptions correctly */
685 ESP = offset; 718 ESP = offset;
686 } 719 }
687 720
  721 +void op_pushw_ss32_T0(void)
  722 +{
  723 + uint32_t offset;
  724 + offset = ESP - 2;
  725 + stw(env->seg_cache[R_SS].base + offset, T0);
  726 + /* modify ESP after to handle exceptions correctly */
  727 + ESP = offset;
  728 +}
  729 +
  730 +void op_pushl_ss16_T0(void)
  731 +{
  732 + uint32_t offset;
  733 + offset = (ESP - 4) & 0xffff;
  734 + stl(env->seg_cache[R_SS].base + offset, T0);
  735 + /* modify ESP after to handle exceptions correctly */
  736 + ESP = (ESP & ~0xffff) | offset;
  737 +}
  738 +
  739 +void op_pushw_ss16_T0(void)
  740 +{
  741 + uint32_t offset;
  742 + offset = (ESP - 2) & 0xffff;
  743 + stw(env->seg_cache[R_SS].base + offset, T0);
  744 + /* modify ESP after to handle exceptions correctly */
  745 + ESP = (ESP & ~0xffff) | offset;
  746 +}
  747 +
  748 +/* NOTE: ESP update is done after */
688 void op_popl_T0(void) 749 void op_popl_T0(void)
689 { 750 {
690 T0 = ldl((void *)ESP); 751 T0 = ldl((void *)ESP);
  752 +}
  753 +
  754 +void op_popw_T0(void)
  755 +{
  756 + T0 = lduw((void *)ESP);
  757 +}
  758 +
  759 +void op_popl_ss32_T0(void)
  760 +{
  761 + T0 = ldl(env->seg_cache[R_SS].base + ESP);
  762 +}
  763 +
  764 +void op_popw_ss32_T0(void)
  765 +{
  766 + T0 = lduw(env->seg_cache[R_SS].base + ESP);
  767 +}
  768 +
  769 +void op_popl_ss16_T0(void)
  770 +{
  771 + T0 = ldl(env->seg_cache[R_SS].base + (ESP & 0xffff));
  772 +}
  773 +
  774 +void op_popw_ss16_T0(void)
  775 +{
  776 + T0 = lduw(env->seg_cache[R_SS].base + (ESP & 0xffff));
  777 +}
  778 +
  779 +void op_addl_ESP_4(void)
  780 +{
691 ESP += 4; 781 ESP += 4;
692 } 782 }
693 783
  784 +void op_addl_ESP_2(void)
  785 +{
  786 + ESP += 2;
  787 +}
  788 +
  789 +void op_addw_ESP_4(void)
  790 +{
  791 + ESP = (ESP & ~0xffff) | ((ESP + 4) & 0xffff);
  792 +}
  793 +
  794 +void op_addw_ESP_2(void)
  795 +{
  796 + ESP = (ESP & ~0xffff) | ((ESP + 2) & 0xffff);
  797 +}
  798 +
694 void op_addl_ESP_im(void) 799 void op_addl_ESP_im(void)
695 { 800 {
696 ESP += PARAM1; 801 ESP += PARAM1;
697 } 802 }
698 803
699 -void op_pushal(void)  
700 -{  
701 - uint8_t *sp;  
702 - sp = (void *)(ESP - 32);  
703 - stl(sp, EDI);  
704 - stl(sp + 4, ESI);  
705 - stl(sp + 8, EBP);  
706 - stl(sp + 12, ESP);  
707 - stl(sp + 16, EBX);  
708 - stl(sp + 20, EDX);  
709 - stl(sp + 24, ECX);  
710 - stl(sp + 28, EAX);  
711 - ESP = (unsigned long)sp;  
712 -}  
713 -  
714 -void op_pushaw(void)  
715 -{  
716 - uint8_t *sp;  
717 - sp = (void *)(ESP - 16);  
718 - stw(sp, EDI);  
719 - stw(sp + 2, ESI);  
720 - stw(sp + 4, EBP);  
721 - stw(sp + 6, ESP);  
722 - stw(sp + 8, EBX);  
723 - stw(sp + 10, EDX);  
724 - stw(sp + 12, ECX);  
725 - stw(sp + 14, EAX);  
726 - ESP = (unsigned long)sp;  
727 -}  
728 -  
729 -void op_popal(void)  
730 -{  
731 - uint8_t *sp;  
732 - sp = (void *)ESP;  
733 - EDI = ldl(sp);  
734 - ESI = ldl(sp + 4);  
735 - EBP = ldl(sp + 8);  
736 - EBX = ldl(sp + 16);  
737 - EDX = ldl(sp + 20);  
738 - ECX = ldl(sp + 24);  
739 - EAX = ldl(sp + 28);  
740 - ESP = (unsigned long)sp + 32;  
741 -}  
742 -  
743 -void op_popaw(void)  
744 -{  
745 - uint8_t *sp;  
746 - sp = (void *)ESP;  
747 - EDI = ldl(sp);  
748 - ESI = ldl(sp + 2);  
749 - EBP = ldl(sp + 4);  
750 - EBX = ldl(sp + 8);  
751 - EDX = ldl(sp + 10);  
752 - ECX = ldl(sp + 12);  
753 - EAX = ldl(sp + 14);  
754 - ESP = (unsigned long)sp + 16;  
755 -}  
756 -  
757 -void op_enterl(void)  
758 -{  
759 - unsigned int bp, frame_temp, level;  
760 - uint8_t *sp;  
761 -  
762 - sp = (void *)ESP;  
763 - bp = EBP;  
764 - sp -= 4;  
765 - stl(sp, bp);  
766 - frame_temp = (unsigned int)sp;  
767 - level = PARAM2;  
768 - if (level) {  
769 - while (level--) {  
770 - bp -= 4;  
771 - sp -= 4;  
772 - stl(sp, bp);  
773 - }  
774 - sp -= 4;  
775 - stl(sp, frame_temp);  
776 - }  
777 - EBP = frame_temp;  
778 - sp -= PARAM1;  
779 - ESP = (int)sp; 804 +void op_addw_ESP_im(void)
  805 +{
  806 + ESP = (ESP & ~0xffff) | ((ESP + PARAM1) & 0xffff);
780 } 807 }
781 808
782 /* rdtsc */ 809 /* rdtsc */
@@ -988,18 +1015,18 @@ void OPPROTO op_jo_cc(void) @@ -988,18 +1015,18 @@ void OPPROTO op_jo_cc(void)
988 int eflags; 1015 int eflags;
989 eflags = cc_table[CC_OP].compute_all(); 1016 eflags = cc_table[CC_OP].compute_all();
990 if (eflags & CC_O) 1017 if (eflags & CC_O)
991 - PC = PARAM1; 1018 + EIP = PARAM1;
992 else 1019 else
993 - PC = PARAM2; 1020 + EIP = PARAM2;
994 FORCE_RET(); 1021 FORCE_RET();
995 } 1022 }
996 1023
997 void OPPROTO op_jb_cc(void) 1024 void OPPROTO op_jb_cc(void)
998 { 1025 {
999 if (cc_table[CC_OP].compute_c()) 1026 if (cc_table[CC_OP].compute_c())
1000 - PC = PARAM1; 1027 + EIP = PARAM1;
1001 else 1028 else
1002 - PC = PARAM2; 1029 + EIP = PARAM2;
1003 FORCE_RET(); 1030 FORCE_RET();
1004 } 1031 }
1005 1032
@@ -1008,9 +1035,9 @@ void OPPROTO op_jz_cc(void) @@ -1008,9 +1035,9 @@ void OPPROTO op_jz_cc(void)
1008 int eflags; 1035 int eflags;
1009 eflags = cc_table[CC_OP].compute_all(); 1036 eflags = cc_table[CC_OP].compute_all();
1010 if (eflags & CC_Z) 1037 if (eflags & CC_Z)
1011 - PC = PARAM1; 1038 + EIP = PARAM1;
1012 else 1039 else
1013 - PC = PARAM2; 1040 + EIP = PARAM2;
1014 FORCE_RET(); 1041 FORCE_RET();
1015 } 1042 }
1016 1043
@@ -1019,9 +1046,9 @@ void OPPROTO op_jbe_cc(void) @@ -1019,9 +1046,9 @@ void OPPROTO op_jbe_cc(void)
1019 int eflags; 1046 int eflags;
1020 eflags = cc_table[CC_OP].compute_all(); 1047 eflags = cc_table[CC_OP].compute_all();
1021 if (eflags & (CC_Z | CC_C)) 1048 if (eflags & (CC_Z | CC_C))
1022 - PC = PARAM1; 1049 + EIP = PARAM1;
1023 else 1050 else
1024 - PC = PARAM2; 1051 + EIP = PARAM2;
1025 FORCE_RET(); 1052 FORCE_RET();
1026 } 1053 }
1027 1054
@@ -1030,9 +1057,9 @@ void OPPROTO op_js_cc(void) @@ -1030,9 +1057,9 @@ void OPPROTO op_js_cc(void)
1030 int eflags; 1057 int eflags;
1031 eflags = cc_table[CC_OP].compute_all(); 1058 eflags = cc_table[CC_OP].compute_all();
1032 if (eflags & CC_S) 1059 if (eflags & CC_S)
1033 - PC = PARAM1; 1060 + EIP = PARAM1;
1034 else 1061 else
1035 - PC = PARAM2; 1062 + EIP = PARAM2;
1036 FORCE_RET(); 1063 FORCE_RET();
1037 } 1064 }
1038 1065
@@ -1041,9 +1068,9 @@ void OPPROTO op_jp_cc(void) @@ -1041,9 +1068,9 @@ void OPPROTO op_jp_cc(void)
1041 int eflags; 1068 int eflags;
1042 eflags = cc_table[CC_OP].compute_all(); 1069 eflags = cc_table[CC_OP].compute_all();
1043 if (eflags & CC_P) 1070 if (eflags & CC_P)
1044 - PC = PARAM1; 1071 + EIP = PARAM1;
1045 else 1072 else
1046 - PC = PARAM2; 1073 + EIP = PARAM2;
1047 FORCE_RET(); 1074 FORCE_RET();
1048 } 1075 }
1049 1076
@@ -1052,9 +1079,9 @@ void OPPROTO op_jl_cc(void) @@ -1052,9 +1079,9 @@ void OPPROTO op_jl_cc(void)
1052 int eflags; 1079 int eflags;
1053 eflags = cc_table[CC_OP].compute_all(); 1080 eflags = cc_table[CC_OP].compute_all();
1054 if ((eflags ^ (eflags >> 4)) & 0x80) 1081 if ((eflags ^ (eflags >> 4)) & 0x80)
1055 - PC = PARAM1; 1082 + EIP = PARAM1;
1056 else 1083 else
1057 - PC = PARAM2; 1084 + EIP = PARAM2;
1058 FORCE_RET(); 1085 FORCE_RET();
1059 } 1086 }
1060 1087
@@ -1063,9 +1090,9 @@ void OPPROTO op_jle_cc(void) @@ -1063,9 +1090,9 @@ void OPPROTO op_jle_cc(void)
1063 int eflags; 1090 int eflags;
1064 eflags = cc_table[CC_OP].compute_all(); 1091 eflags = cc_table[CC_OP].compute_all();
1065 if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) 1092 if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z))
1066 - PC = PARAM1; 1093 + EIP = PARAM1;
1067 else 1094 else
1068 - PC = PARAM2; 1095 + EIP = PARAM2;
1069 FORCE_RET(); 1096 FORCE_RET();
1070 } 1097 }
1071 1098
opc-i386.h
@@ -202,7 +202,12 @@ DEF(idivw_AX_T0) @@ -202,7 +202,12 @@ DEF(idivw_AX_T0)
202 DEF(divl_EAX_T0) 202 DEF(divl_EAX_T0)
203 DEF(idivl_EAX_T0) 203 DEF(idivl_EAX_T0)
204 DEF(movl_T0_im) 204 DEF(movl_T0_im)
  205 +DEF(addl_T0_im)
  206 +DEF(andl_T0_ffff)
  207 +DEF(movl_T0_T1)
205 DEF(movl_T1_im) 208 DEF(movl_T1_im)
  209 +DEF(addl_T1_im)
  210 +DEF(movl_T1_A0)
206 DEF(movl_A0_im) 211 DEF(movl_A0_im)
207 DEF(addl_A0_im) 212 DEF(addl_A0_im)
208 DEF(andl_A0_ffff) 213 DEF(andl_A0_ffff)
@@ -398,14 +403,23 @@ DEF(movsbw_AX_AL) @@ -398,14 +403,23 @@ DEF(movsbw_AX_AL)
398 DEF(movslq_EDX_EAX) 403 DEF(movslq_EDX_EAX)
399 DEF(movswl_DX_AX) 404 DEF(movswl_DX_AX)
400 DEF(pushl_T0) 405 DEF(pushl_T0)
401 -DEF(pushl_T1) 406 +DEF(pushw_T0)
  407 +DEF(pushl_ss32_T0)
  408 +DEF(pushw_ss32_T0)
  409 +DEF(pushl_ss16_T0)
  410 +DEF(pushw_ss16_T0)
402 DEF(popl_T0) 411 DEF(popl_T0)
  412 +DEF(popw_T0)
  413 +DEF(popl_ss32_T0)
  414 +DEF(popw_ss32_T0)
  415 +DEF(popl_ss16_T0)
  416 +DEF(popw_ss16_T0)
  417 +DEF(addl_ESP_4)
  418 +DEF(addl_ESP_2)
  419 +DEF(addw_ESP_4)
  420 +DEF(addw_ESP_2)
403 DEF(addl_ESP_im) 421 DEF(addl_ESP_im)
404 -DEF(pushal)  
405 -DEF(pushaw)  
406 -DEF(popal)  
407 -DEF(popaw)  
408 -DEF(enterl) 422 +DEF(addw_ESP_im)
409 DEF(rdtsc) 423 DEF(rdtsc)
410 DEF(aam) 424 DEF(aam)
411 DEF(aad) 425 DEF(aad)
ops_template.h
@@ -214,18 +214,18 @@ void OPPROTO glue(op_jb_sub, SUFFIX)(void) @@ -214,18 +214,18 @@ void OPPROTO glue(op_jb_sub, SUFFIX)(void)
214 src2 = CC_SRC - CC_DST; 214 src2 = CC_SRC - CC_DST;
215 215
216 if ((DATA_TYPE)src1 < (DATA_TYPE)src2) 216 if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
217 - PC = PARAM1; 217 + EIP = PARAM1;
218 else 218 else
219 - PC = PARAM2; 219 + EIP = PARAM2;
220 FORCE_RET(); 220 FORCE_RET();
221 } 221 }
222 222
223 void OPPROTO glue(op_jz_sub, SUFFIX)(void) 223 void OPPROTO glue(op_jz_sub, SUFFIX)(void)
224 { 224 {
225 if ((DATA_TYPE)CC_DST == 0) 225 if ((DATA_TYPE)CC_DST == 0)
226 - PC = PARAM1; 226 + EIP = PARAM1;
227 else 227 else
228 - PC = PARAM2; 228 + EIP = PARAM2;
229 FORCE_RET(); 229 FORCE_RET();
230 } 230 }
231 231
@@ -236,18 +236,18 @@ void OPPROTO glue(op_jbe_sub, SUFFIX)(void) @@ -236,18 +236,18 @@ void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
236 src2 = CC_SRC - CC_DST; 236 src2 = CC_SRC - CC_DST;
237 237
238 if ((DATA_TYPE)src1 <= (DATA_TYPE)src2) 238 if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
239 - PC = PARAM1; 239 + EIP = PARAM1;
240 else 240 else
241 - PC = PARAM2; 241 + EIP = PARAM2;
242 FORCE_RET(); 242 FORCE_RET();
243 } 243 }
244 244
245 void OPPROTO glue(op_js_sub, SUFFIX)(void) 245 void OPPROTO glue(op_js_sub, SUFFIX)(void)
246 { 246 {
247 if (CC_DST & SIGN_MASK) 247 if (CC_DST & SIGN_MASK)
248 - PC = PARAM1; 248 + EIP = PARAM1;
249 else 249 else
250 - PC = PARAM2; 250 + EIP = PARAM2;
251 FORCE_RET(); 251 FORCE_RET();
252 } 252 }
253 253
@@ -258,9 +258,9 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(void) @@ -258,9 +258,9 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(void)
258 src2 = CC_SRC - CC_DST; 258 src2 = CC_SRC - CC_DST;
259 259
260 if ((DATA_STYPE)src1 < (DATA_STYPE)src2) 260 if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
261 - PC = PARAM1; 261 + EIP = PARAM1;
262 else 262 else
263 - PC = PARAM2; 263 + EIP = PARAM2;
264 FORCE_RET(); 264 FORCE_RET();
265 } 265 }
266 266
@@ -271,9 +271,9 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(void) @@ -271,9 +271,9 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(void)
271 src2 = CC_SRC - CC_DST; 271 src2 = CC_SRC - CC_DST;
272 272
273 if ((DATA_STYPE)src1 <= (DATA_STYPE)src2) 273 if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
274 - PC = PARAM1; 274 + EIP = PARAM1;
275 else 275 else
276 - PC = PARAM2; 276 + EIP = PARAM2;
277 FORCE_RET(); 277 FORCE_RET();
278 } 278 }
279 279
@@ -289,9 +289,9 @@ void OPPROTO glue(op_loopnz, SUFFIX)(void) @@ -289,9 +289,9 @@ void OPPROTO glue(op_loopnz, SUFFIX)(void)
289 tmp = (ECX - 1) & DATA_MASK; 289 tmp = (ECX - 1) & DATA_MASK;
290 ECX = (ECX & ~DATA_MASK) | tmp; 290 ECX = (ECX & ~DATA_MASK) | tmp;
291 if (tmp != 0 && !(eflags & CC_Z)) 291 if (tmp != 0 && !(eflags & CC_Z))
292 - PC = PARAM1; 292 + EIP = PARAM1;
293 else 293 else
294 - PC = PARAM2; 294 + EIP = PARAM2;
295 FORCE_RET(); 295 FORCE_RET();
296 } 296 }
297 297
@@ -303,9 +303,9 @@ void OPPROTO glue(op_loopz, SUFFIX)(void) @@ -303,9 +303,9 @@ void OPPROTO glue(op_loopz, SUFFIX)(void)
303 tmp = (ECX - 1) & DATA_MASK; 303 tmp = (ECX - 1) & DATA_MASK;
304 ECX = (ECX & ~DATA_MASK) | tmp; 304 ECX = (ECX & ~DATA_MASK) | tmp;
305 if (tmp != 0 && (eflags & CC_Z)) 305 if (tmp != 0 && (eflags & CC_Z))
306 - PC = PARAM1; 306 + EIP = PARAM1;
307 else 307 else
308 - PC = PARAM2; 308 + EIP = PARAM2;
309 FORCE_RET(); 309 FORCE_RET();
310 } 310 }
311 311
@@ -315,18 +315,18 @@ void OPPROTO glue(op_loop, SUFFIX)(void) @@ -315,18 +315,18 @@ void OPPROTO glue(op_loop, SUFFIX)(void)
315 tmp = (ECX - 1) & DATA_MASK; 315 tmp = (ECX - 1) & DATA_MASK;
316 ECX = (ECX & ~DATA_MASK) | tmp; 316 ECX = (ECX & ~DATA_MASK) | tmp;
317 if (tmp != 0) 317 if (tmp != 0)
318 - PC = PARAM1; 318 + EIP = PARAM1;
319 else 319 else
320 - PC = PARAM2; 320 + EIP = PARAM2;
321 FORCE_RET(); 321 FORCE_RET();
322 } 322 }
323 323
324 void OPPROTO glue(op_jecxz, SUFFIX)(void) 324 void OPPROTO glue(op_jecxz, SUFFIX)(void)
325 { 325 {
326 if ((DATA_TYPE)ECX == 0) 326 if ((DATA_TYPE)ECX == 0)
327 - PC = PARAM1; 327 + EIP = PARAM1;
328 else 328 else
329 - PC = PARAM2; 329 + EIP = PARAM2;
330 FORCE_RET(); 330 FORCE_RET();
331 } 331 }
332 332
translate-i386.c
@@ -92,11 +92,13 @@ typedef struct DisasContext { @@ -92,11 +92,13 @@ typedef struct DisasContext {
92 /* current insn context */ 92 /* current insn context */
93 int prefix; 93 int prefix;
94 int aflag, dflag; 94 int aflag, dflag;
95 - uint8_t *pc; /* current pc */ 95 + uint8_t *pc; /* pc = eip + cs_base */
96 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU 96 int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
97 static state change (stop translation) */ 97 static state change (stop translation) */
98 /* current block context */ 98 /* current block context */
  99 + uint8_t *cs_base; /* base of CS segment */
99 int code32; /* 32 bit code segment */ 100 int code32; /* 32 bit code segment */
  101 + int ss32; /* 32 bit stack segment */
100 int cc_op; /* current CC operation */ 102 int cc_op; /* current CC operation */
101 int addseg; /* non zero if either DS/ES/SS have a non zero base */ 103 int addseg; /* non zero if either DS/ES/SS have a non zero base */
102 int f_st; /* currently unused */ 104 int f_st; /* currently unused */
@@ -1051,7 +1053,7 @@ static inline uint32_t insn_get(DisasContext *s, int ot) @@ -1051,7 +1053,7 @@ static inline uint32_t insn_get(DisasContext *s, int ot)
1051 return ret; 1053 return ret;
1052 } 1054 }
1053 1055
1054 -static void gen_jcc(DisasContext *s, int b, int val) 1056 +static inline void gen_jcc(DisasContext *s, int b, int val, int next_eip)
1055 { 1057 {
1056 int inv, jcc_op; 1058 int inv, jcc_op;
1057 GenOpFunc2 *func; 1059 GenOpFunc2 *func;
@@ -1112,9 +1114,9 @@ static void gen_jcc(DisasContext *s, int b, int val) @@ -1112,9 +1114,9 @@ static void gen_jcc(DisasContext *s, int b, int val)
1112 break; 1114 break;
1113 } 1115 }
1114 if (!inv) { 1116 if (!inv) {
1115 - func(val, (long)s->pc); 1117 + func(val, next_eip);
1116 } else { 1118 } else {
1117 - func((long)s->pc, val); 1119 + func(next_eip, val);
1118 } 1120 }
1119 } 1121 }
1120 1122
@@ -1176,7 +1178,7 @@ static void gen_setcc(DisasContext *s, int b) @@ -1176,7 +1178,7 @@ static void gen_setcc(DisasContext *s, int b)
1176 } 1178 }
1177 1179
1178 /* move T0 to seg_reg and compute if the CPU state may change */ 1180 /* move T0 to seg_reg and compute if the CPU state may change */
1179 -void gen_movl_seg_T0(DisasContext *s, int seg_reg) 1181 +static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
1180 { 1182 {
1181 gen_op_movl_seg_T0(seg_reg); 1183 gen_op_movl_seg_T0(seg_reg);
1182 if (!s->addseg && seg_reg < R_FS) 1184 if (!s->addseg && seg_reg < R_FS)
@@ -1184,6 +1186,148 @@ void gen_movl_seg_T0(DisasContext *s, int seg_reg) @@ -1184,6 +1186,148 @@ void gen_movl_seg_T0(DisasContext *s, int seg_reg)
1184 have a non zero base */ 1186 have a non zero base */
1185 } 1187 }
1186 1188
  1189 +/* generate a push. It depends on ss32, addseg and dflag */
  1190 +static void gen_push_T0(DisasContext *s)
  1191 +{
  1192 + if (s->ss32) {
  1193 + if (!s->addseg) {
  1194 + if (s->dflag)
  1195 + gen_op_pushl_T0();
  1196 + else
  1197 + gen_op_pushw_T0();
  1198 + } else {
  1199 + if (s->dflag)
  1200 + gen_op_pushl_ss32_T0();
  1201 + else
  1202 + gen_op_pushw_ss32_T0();
  1203 + }
  1204 + } else {
  1205 + if (s->dflag)
  1206 + gen_op_pushl_ss16_T0();
  1207 + else
  1208 + gen_op_pushw_ss16_T0();
  1209 + }
  1210 +}
  1211 +
  1212 +/* two step pop is necessary for precise exceptions */
  1213 +static void gen_pop_T0(DisasContext *s)
  1214 +{
  1215 + if (s->ss32) {
  1216 + if (!s->addseg) {
  1217 + if (s->dflag)
  1218 + gen_op_popl_T0();
  1219 + else
  1220 + gen_op_popw_T0();
  1221 + } else {
  1222 + if (s->dflag)
  1223 + gen_op_popl_ss32_T0();
  1224 + else
  1225 + gen_op_popw_ss32_T0();
  1226 + }
  1227 + } else {
  1228 + if (s->dflag)
  1229 + gen_op_popl_ss16_T0();
  1230 + else
  1231 + gen_op_popw_ss16_T0();
  1232 + }
  1233 +}
  1234 +
  1235 +static void gen_pop_update(DisasContext *s)
  1236 +{
  1237 + if (s->ss32) {
  1238 + if (s->dflag)
  1239 + gen_op_addl_ESP_4();
  1240 + else
  1241 + gen_op_addl_ESP_2();
  1242 + } else {
  1243 + if (s->dflag)
  1244 + gen_op_addw_ESP_4();
  1245 + else
  1246 + gen_op_addw_ESP_2();
  1247 + }
  1248 +}
  1249 +
  1250 +/* NOTE: wrap around in 16 bit not fully handled */
  1251 +static void gen_pusha(DisasContext *s)
  1252 +{
  1253 + int i;
  1254 + gen_op_movl_A0_ESP();
  1255 + gen_op_addl_A0_im(-16 << s->dflag);
  1256 + if (!s->ss32)
  1257 + gen_op_andl_A0_ffff();
  1258 + gen_op_movl_T1_A0();
  1259 + if (s->addseg)
  1260 + gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[R_SS].base));
  1261 + for(i = 0;i < 8; i++) {
  1262 + gen_op_mov_TN_reg[OT_LONG][0][7 - i]();
  1263 + gen_op_st_T0_A0[OT_WORD + s->dflag]();
  1264 + gen_op_addl_A0_im(2 << s->dflag);
  1265 + }
  1266 + gen_op_mov_reg_T1[OT_WORD + s->dflag][R_ESP]();
  1267 +}
  1268 +
  1269 +/* NOTE: wrap around in 16 bit not fully handled */
  1270 +static void gen_popa(DisasContext *s)
  1271 +{
  1272 + int i;
  1273 + gen_op_movl_A0_ESP();
  1274 + if (!s->ss32)
  1275 + gen_op_andl_A0_ffff();
  1276 + gen_op_movl_T1_A0();
  1277 + gen_op_addl_T1_im(16 << s->dflag);
  1278 + if (s->addseg)
  1279 + gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[R_SS].base));
  1280 + for(i = 0;i < 8; i++) {
  1281 + /* ESP is not reloaded */
  1282 + if (i != 3) {
  1283 + gen_op_ld_T0_A0[OT_WORD + s->dflag]();
  1284 + gen_op_mov_reg_T0[OT_WORD + s->dflag][7 - i]();
  1285 + }
  1286 + gen_op_addl_A0_im(2 << s->dflag);
  1287 + }
  1288 + gen_op_mov_reg_T1[OT_WORD + s->dflag][R_ESP]();
  1289 +}
  1290 +
  1291 +/* NOTE: wrap around in 16 bit not fully handled */
  1292 +/* XXX: check this */
  1293 +static void gen_enter(DisasContext *s, int esp_addend, int level)
  1294 +{
  1295 + int ot, level1, addend, opsize;
  1296 +
  1297 + ot = s->dflag + OT_WORD;
  1298 + level &= 0x1f;
  1299 + level1 = level;
  1300 + opsize = 2 << s->dflag;
  1301 +
  1302 + gen_op_movl_A0_ESP();
  1303 + gen_op_addl_A0_im(-opsize);
  1304 + if (!s->ss32)
  1305 + gen_op_andl_A0_ffff();
  1306 + gen_op_movl_T1_A0();
  1307 + if (s->addseg)
  1308 + gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[R_SS].base));
  1309 + /* push bp */
  1310 + gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
  1311 + gen_op_st_T0_A0[ot]();
  1312 + if (level) {
  1313 + while (level--) {
  1314 + gen_op_addl_A0_im(-opsize);
  1315 + gen_op_addl_T0_im(-opsize);
  1316 + gen_op_st_T0_A0[ot]();
  1317 + }
  1318 + gen_op_addl_A0_im(-opsize);
  1319 + /* XXX: add st_T1_A0 ? */
  1320 + gen_op_movl_T0_T1();
  1321 + gen_op_st_T0_A0[ot]();
  1322 + }
  1323 + gen_op_mov_reg_T1[ot][R_EBP]();
  1324 + addend = -esp_addend;
  1325 + if (level1)
  1326 + addend -= opsize * (level1 + 1);
  1327 + gen_op_addl_T1_im(addend);
  1328 + gen_op_mov_reg_T1[ot][R_ESP]();
  1329 +}
  1330 +
1187 /* return the next pc address. Return -1 if no insn found. *is_jmp_ptr 1331 /* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
1188 is set to true if the instruction sets the PC (last instruction of 1332 is set to true if the instruction sets the PC (last instruction of
1189 a basic block) */ 1333 a basic block) */
@@ -1192,6 +1336,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1192,6 +1336,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1192 int b, prefixes, aflag, dflag; 1336 int b, prefixes, aflag, dflag;
1193 int shift, ot; 1337 int shift, ot;
1194 int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val; 1338 int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
  1339 + unsigned int next_eip;
1195 1340
1196 s->pc = pc_start; 1341 s->pc = pc_start;
1197 prefixes = 0; 1342 prefixes = 0;
@@ -1492,7 +1637,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1492,7 +1637,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1492 } 1637 }
1493 if (mod != 3) { 1638 if (mod != 3) {
1494 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 1639 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1495 - gen_op_ld_T0_A0[ot](); 1640 + if (op != 3 && op != 5)
  1641 + gen_op_ld_T0_A0[ot]();
1496 } else { 1642 } else {
1497 gen_op_mov_TN_reg[ot][0][rm](); 1643 gen_op_mov_TN_reg[ot][0][rm]();
1498 } 1644 }
@@ -1513,17 +1659,48 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1513,17 +1659,48 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1513 gen_op_mov_reg_T0[ot][rm](); 1659 gen_op_mov_reg_T0[ot][rm]();
1514 break; 1660 break;
1515 case 2: /* call Ev */ 1661 case 2: /* call Ev */
1516 - gen_op_movl_T1_im((long)s->pc);  
1517 - gen_op_pushl_T1(); 1662 + /* XXX: optimize if memory (no and is necessary) */
  1663 + if (s->dflag == 0)
  1664 + gen_op_andl_T0_ffff();
  1665 + gen_op_jmp_T0();
  1666 + next_eip = s->pc - s->cs_base;
  1667 + gen_op_movl_T0_im(next_eip);
  1668 + gen_push_T0(s);
  1669 + s->is_jmp = 1;
  1670 + break;
  1671 + case 3: /* lcall Ev */
  1672 + /* push return segment + offset */
  1673 + gen_op_movl_T0_seg(R_CS);
  1674 + gen_push_T0(s);
  1675 + next_eip = s->pc - s->cs_base;
  1676 + gen_op_movl_T0_im(next_eip);
  1677 + gen_push_T0(s);
  1678 +
  1679 + gen_op_ld_T1_A0[ot]();
  1680 + gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
  1681 + gen_op_lduw_T0_A0();
  1682 + gen_movl_seg_T0(s, R_CS);
  1683 + gen_op_movl_T0_T1();
1518 gen_op_jmp_T0(); 1684 gen_op_jmp_T0();
1519 s->is_jmp = 1; 1685 s->is_jmp = 1;
1520 break; 1686 break;
1521 case 4: /* jmp Ev */ 1687 case 4: /* jmp Ev */
  1688 + if (s->dflag == 0)
  1689 + gen_op_andl_T0_ffff();
  1690 + gen_op_jmp_T0();
  1691 + s->is_jmp = 1;
  1692 + break;
  1693 + case 5: /* ljmp Ev */
  1694 + gen_op_ld_T1_A0[ot]();
  1695 + gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
  1696 + gen_op_lduw_T0_A0();
  1697 + gen_movl_seg_T0(s, R_CS);
  1698 + gen_op_movl_T0_T1();
1522 gen_op_jmp_T0(); 1699 gen_op_jmp_T0();
1523 s->is_jmp = 1; 1700 s->is_jmp = 1;
1524 break; 1701 break;
1525 case 6: /* push Ev */ 1702 case 6: /* push Ev */
1526 - gen_op_pushl_T0(); 1703 + gen_push_T0(s);
1527 break; 1704 break;
1528 default: 1705 default:
1529 goto illegal_op; 1706 goto illegal_op;
@@ -1653,23 +1830,19 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1653,23 +1830,19 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1653 /* push/pop */ 1830 /* push/pop */
1654 case 0x50 ... 0x57: /* push */ 1831 case 0x50 ... 0x57: /* push */
1655 gen_op_mov_TN_reg[OT_LONG][0][b & 7](); 1832 gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
1656 - gen_op_pushl_T0(); 1833 + gen_push_T0(s);
1657 break; 1834 break;
1658 case 0x58 ... 0x5f: /* pop */ 1835 case 0x58 ... 0x5f: /* pop */
1659 - gen_op_popl_T0();  
1660 - gen_op_mov_reg_T0[OT_LONG][b & 7](); 1836 + ot = dflag ? OT_LONG : OT_WORD;
  1837 + gen_pop_T0(s);
  1838 + gen_op_mov_reg_T0[ot][b & 7]();
  1839 + gen_pop_update(s);
1661 break; 1840 break;
1662 case 0x60: /* pusha */ 1841 case 0x60: /* pusha */
1663 - if (s->dflag)  
1664 - gen_op_pushal();  
1665 - else  
1666 - gen_op_pushaw(); 1842 + gen_pusha(s);
1667 break; 1843 break;
1668 case 0x61: /* popa */ 1844 case 0x61: /* popa */
1669 - if (s->dflag)  
1670 - gen_op_popal();  
1671 - else  
1672 - gen_op_popaw(); 1845 + gen_popa(s);
1673 break; 1846 break;
1674 case 0x68: /* push Iv */ 1847 case 0x68: /* push Iv */
1675 case 0x6a: 1848 case 0x6a:
@@ -1679,13 +1852,14 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1679,13 +1852,14 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1679 else 1852 else
1680 val = (int8_t)insn_get(s, OT_BYTE); 1853 val = (int8_t)insn_get(s, OT_BYTE);
1681 gen_op_movl_T0_im(val); 1854 gen_op_movl_T0_im(val);
1682 - gen_op_pushl_T0(); 1855 + gen_push_T0(s);
1683 break; 1856 break;
1684 case 0x8f: /* pop Ev */ 1857 case 0x8f: /* pop Ev */
1685 ot = dflag ? OT_LONG : OT_WORD; 1858 ot = dflag ? OT_LONG : OT_WORD;
1686 modrm = ldub(s->pc++); 1859 modrm = ldub(s->pc++);
1687 - gen_op_popl_T0(); 1860 + gen_pop_T0(s);
1688 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); 1861 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
  1862 + gen_pop_update(s);
1689 break; 1863 break;
1690 case 0xc8: /* enter */ 1864 case 0xc8: /* enter */
1691 { 1865 {
@@ -1693,38 +1867,47 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1693,38 +1867,47 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1693 val = lduw(s->pc); 1867 val = lduw(s->pc);
1694 s->pc += 2; 1868 s->pc += 2;
1695 level = ldub(s->pc++); 1869 level = ldub(s->pc++);
1696 - level &= 0x1f;  
1697 - gen_op_enterl(val, level); 1870 + gen_enter(s, val, level);
1698 } 1871 }
1699 break; 1872 break;
1700 case 0xc9: /* leave */ 1873 case 0xc9: /* leave */
1701 - gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();  
1702 - gen_op_mov_reg_T0[OT_LONG][R_ESP]();  
1703 - gen_op_popl_T0();  
1704 - gen_op_mov_reg_T0[OT_LONG][R_EBP](); 1874 + /* XXX: exception not precise (ESP is update before potential exception) */
  1875 + if (s->ss32) {
  1876 + gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
  1877 + gen_op_mov_reg_T0[OT_LONG][R_ESP]();
  1878 + } else {
  1879 + gen_op_mov_TN_reg[OT_WORD][0][R_EBP]();
  1880 + gen_op_mov_reg_T0[OT_WORD][R_ESP]();
  1881 + }
  1882 + gen_pop_T0(s);
  1883 + ot = dflag ? OT_LONG : OT_WORD;
  1884 + gen_op_mov_reg_T0[ot][R_EBP]();
  1885 + gen_pop_update(s);
1705 break; 1886 break;
1706 case 0x06: /* push es */ 1887 case 0x06: /* push es */
1707 case 0x0e: /* push cs */ 1888 case 0x0e: /* push cs */
1708 case 0x16: /* push ss */ 1889 case 0x16: /* push ss */
1709 case 0x1e: /* push ds */ 1890 case 0x1e: /* push ds */
1710 gen_op_movl_T0_seg(b >> 3); 1891 gen_op_movl_T0_seg(b >> 3);
1711 - gen_op_pushl_T0(); 1892 + gen_push_T0(s);
1712 break; 1893 break;
1713 case 0x1a0: /* push fs */ 1894 case 0x1a0: /* push fs */
1714 case 0x1a8: /* push gs */ 1895 case 0x1a8: /* push gs */
1715 gen_op_movl_T0_seg(((b >> 3) & 7) + R_FS); 1896 gen_op_movl_T0_seg(((b >> 3) & 7) + R_FS);
1716 - gen_op_pushl_T0(); 1897 + gen_push_T0(s);
1717 break; 1898 break;
1718 case 0x07: /* pop es */ 1899 case 0x07: /* pop es */
1719 case 0x17: /* pop ss */ 1900 case 0x17: /* pop ss */
1720 case 0x1f: /* pop ds */ 1901 case 0x1f: /* pop ds */
1721 - gen_op_popl_T0(); 1902 + gen_pop_T0(s);
1722 gen_movl_seg_T0(s, b >> 3); 1903 gen_movl_seg_T0(s, b >> 3);
  1904 + gen_pop_update(s);
1723 break; 1905 break;
1724 case 0x1a1: /* pop fs */ 1906 case 0x1a1: /* pop fs */
1725 case 0x1a9: /* pop gs */ 1907 case 0x1a9: /* pop gs */
1726 - gen_op_popl_T0(); 1908 + gen_pop_T0(s);
1727 gen_movl_seg_T0(s, ((b >> 3) & 7) + R_FS); 1909 gen_movl_seg_T0(s, ((b >> 3) & 7) + R_FS);
  1910 + gen_pop_update(s);
1728 break; 1911 break;
1729 1912
1730 /**************************/ 1913 /**************************/
@@ -1775,7 +1958,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1775,7 +1958,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1775 modrm = ldub(s->pc++); 1958 modrm = ldub(s->pc++);
1776 reg = (modrm >> 3) & 7; 1959 reg = (modrm >> 3) & 7;
1777 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); 1960 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1778 - if (reg >= 6) 1961 + if (reg >= 6 || reg == R_CS)
1779 goto illegal_op; 1962 goto illegal_op;
1780 gen_movl_seg_T0(s, reg); 1963 gen_movl_seg_T0(s, reg);
1781 break; 1964 break;
@@ -2585,42 +2768,130 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2585,42 +2768,130 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2585 /************************/ 2768 /************************/
2586 /* control */ 2769 /* control */
2587 case 0xc2: /* ret im */ 2770 case 0xc2: /* ret im */
2588 - /* XXX: handle stack pop ? */  
2589 val = ldsw(s->pc); 2771 val = ldsw(s->pc);
2590 s->pc += 2; 2772 s->pc += 2;
2591 - gen_op_popl_T0();  
2592 - gen_op_addl_ESP_im(val); 2773 + gen_pop_T0(s);
  2774 + if (s->ss32)
  2775 + gen_op_addl_ESP_im(val + (2 << s->dflag));
  2776 + else
  2777 + gen_op_addw_ESP_im(val + (2 << s->dflag));
  2778 + if (s->dflag == 0)
  2779 + gen_op_andl_T0_ffff();
2593 gen_op_jmp_T0(); 2780 gen_op_jmp_T0();
2594 s->is_jmp = 1; 2781 s->is_jmp = 1;
2595 break; 2782 break;
2596 case 0xc3: /* ret */ 2783 case 0xc3: /* ret */
2597 - gen_op_popl_T0(); 2784 + gen_pop_T0(s);
  2785 + gen_pop_update(s);
  2786 + if (s->dflag == 0)
  2787 + gen_op_andl_T0_ffff();
2598 gen_op_jmp_T0(); 2788 gen_op_jmp_T0();
2599 s->is_jmp = 1; 2789 s->is_jmp = 1;
2600 break; 2790 break;
2601 - case 0xe8: /* call */  
2602 - val = insn_get(s, OT_LONG);  
2603 - val += (long)s->pc;  
2604 - gen_op_movl_T1_im((long)s->pc);  
2605 - gen_op_pushl_T1();  
2606 - gen_op_jmp_im(val); 2791 + case 0xca: /* lret im */
  2792 + val = ldsw(s->pc);
  2793 + s->pc += 2;
  2794 + /* pop offset */
  2795 + gen_pop_T0(s);
  2796 + if (s->dflag == 0)
  2797 + gen_op_andl_T0_ffff();
  2798 + gen_op_jmp_T0();
  2799 + gen_pop_update(s);
  2800 + /* pop selector */
  2801 + gen_pop_T0(s);
  2802 + gen_movl_seg_T0(s, R_CS);
  2803 + gen_pop_update(s);
  2804 + /* add stack offset */
  2805 + if (s->ss32)
  2806 + gen_op_addl_ESP_im(val + (2 << s->dflag));
  2807 + else
  2808 + gen_op_addw_ESP_im(val + (2 << s->dflag));
  2809 + s->is_jmp = 1;
  2810 + break;
  2811 + case 0xcb: /* lret */
  2812 + /* pop offset */
  2813 + gen_pop_T0(s);
  2814 + if (s->dflag == 0)
  2815 + gen_op_andl_T0_ffff();
  2816 + gen_op_jmp_T0();
  2817 + gen_pop_update(s);
  2818 + /* pop selector */
  2819 + gen_pop_T0(s);
  2820 + gen_movl_seg_T0(s, R_CS);
  2821 + gen_pop_update(s);
2607 s->is_jmp = 1; 2822 s->is_jmp = 1;
2608 break; 2823 break;
  2824 + case 0xe8: /* call im */
  2825 + {
  2826 + unsigned int next_eip;
  2827 + ot = dflag ? OT_LONG : OT_WORD;
  2828 + val = insn_get(s, ot);
  2829 + next_eip = s->pc - s->cs_base;
  2830 + val += next_eip;
  2831 + if (s->dflag == 0)
  2832 + val &= 0xffff;
  2833 + gen_op_movl_T0_im(next_eip);
  2834 + gen_push_T0(s);
  2835 + gen_op_jmp_im(val);
  2836 + s->is_jmp = 1;
  2837 + }
  2838 + break;
  2839 + case 0x9a: /* lcall im */
  2840 + {
  2841 + unsigned int selector, offset;
  2842 +
  2843 + ot = dflag ? OT_LONG : OT_WORD;
  2844 + offset = insn_get(s, ot);
  2845 + selector = insn_get(s, OT_WORD);
  2846 +
  2847 + /* push return segment + offset */
  2848 + gen_op_movl_T0_seg(R_CS);
  2849 + gen_push_T0(s);
  2850 + next_eip = s->pc - s->cs_base;
  2851 + gen_op_movl_T0_im(next_eip);
  2852 + gen_push_T0(s);
  2853 +
  2854 + /* change cs and pc */
  2855 + gen_op_movl_T0_im(selector);
  2856 + gen_movl_seg_T0(s, R_CS);
  2857 + gen_op_jmp_im((unsigned long)offset);
  2858 + s->is_jmp = 1;
  2859 + }
  2860 + break;
2609 case 0xe9: /* jmp */ 2861 case 0xe9: /* jmp */
2610 - val = insn_get(s, OT_LONG);  
2611 - val += (long)s->pc; 2862 + ot = dflag ? OT_LONG : OT_WORD;
  2863 + val = insn_get(s, ot);
  2864 + val += s->pc - s->cs_base;
  2865 + if (s->dflag == 0)
  2866 + val = val & 0xffff;
2612 gen_op_jmp_im(val); 2867 gen_op_jmp_im(val);
2613 s->is_jmp = 1; 2868 s->is_jmp = 1;
2614 break; 2869 break;
  2870 + case 0xea: /* ljmp im */
  2871 + {
  2872 + unsigned int selector, offset;
  2873 +
  2874 + ot = dflag ? OT_LONG : OT_WORD;
  2875 + offset = insn_get(s, ot);
  2876 + selector = insn_get(s, OT_WORD);
  2877 +
  2878 + /* change cs and pc */
  2879 + gen_op_movl_T0_im(selector);
  2880 + gen_movl_seg_T0(s, R_CS);
  2881 + gen_op_jmp_im((unsigned long)offset);
  2882 + s->is_jmp = 1;
  2883 + }
  2884 + break;
2615 case 0xeb: /* jmp Jb */ 2885 case 0xeb: /* jmp Jb */
2616 val = (int8_t)insn_get(s, OT_BYTE); 2886 val = (int8_t)insn_get(s, OT_BYTE);
2617 - val += (long)s->pc; 2887 + val += s->pc - s->cs_base;
  2888 + if (s->dflag == 0)
  2889 + val = val & 0xffff;
2618 gen_op_jmp_im(val); 2890 gen_op_jmp_im(val);
2619 s->is_jmp = 1; 2891 s->is_jmp = 1;
2620 break; 2892 break;
2621 case 0x70 ... 0x7f: /* jcc Jb */ 2893 case 0x70 ... 0x7f: /* jcc Jb */
2622 val = (int8_t)insn_get(s, OT_BYTE); 2894 val = (int8_t)insn_get(s, OT_BYTE);
2623 - val += (long)s->pc;  
2624 goto do_jcc; 2895 goto do_jcc;
2625 case 0x180 ... 0x18f: /* jcc Jv */ 2896 case 0x180 ... 0x18f: /* jcc Jv */
2626 if (dflag) { 2897 if (dflag) {
@@ -2628,9 +2899,12 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2628,9 +2899,12 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2628 } else { 2899 } else {
2629 val = (int16_t)insn_get(s, OT_WORD); 2900 val = (int16_t)insn_get(s, OT_WORD);
2630 } 2901 }
2631 - val += (long)s->pc; /* XXX: fix 16 bit wrap */  
2632 do_jcc: 2902 do_jcc:
2633 - gen_jcc(s, b, val); 2903 + next_eip = s->pc - s->cs_base;
  2904 + val += next_eip;
  2905 + if (s->dflag == 0)
  2906 + val &= 0xffff;
  2907 + gen_jcc(s, b, val, next_eip);
2634 s->is_jmp = 1; 2908 s->is_jmp = 1;
2635 break; 2909 break;
2636 2910
@@ -2661,11 +2935,12 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2661,11 +2935,12 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2661 if (s->cc_op != CC_OP_DYNAMIC) 2935 if (s->cc_op != CC_OP_DYNAMIC)
2662 gen_op_set_cc_op(s->cc_op); 2936 gen_op_set_cc_op(s->cc_op);
2663 gen_op_movl_T0_eflags(); 2937 gen_op_movl_T0_eflags();
2664 - gen_op_pushl_T0(); 2938 + gen_push_T0(s);
2665 break; 2939 break;
2666 case 0x9d: /* popf */ 2940 case 0x9d: /* popf */
2667 - gen_op_popl_T0(); 2941 + gen_pop_T0(s);
2668 gen_op_movl_eflags_T0(); 2942 gen_op_movl_eflags_T0();
  2943 + gen_pop_update(s);
2669 s->cc_op = CC_OP_EFLAGS; 2944 s->cc_op = CC_OP_EFLAGS;
2670 break; 2945 break;
2671 case 0x9e: /* sahf */ 2946 case 0x9e: /* sahf */
@@ -2860,8 +3135,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2860,8 +3135,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2860 case 0xe2: /* loop */ 3135 case 0xe2: /* loop */
2861 case 0xe3: /* jecxz */ 3136 case 0xe3: /* jecxz */
2862 val = (int8_t)insn_get(s, OT_BYTE); 3137 val = (int8_t)insn_get(s, OT_BYTE);
2863 - val += (long)s->pc;  
2864 - gen_op_loop[s->aflag][b & 3](val, (long)s->pc); 3138 + next_eip = s->pc - s->cs_base;
  3139 + val += next_eip;
  3140 + if (s->dflag == 0)
  3141 + val &= 0xffff;
  3142 + gen_op_loop[s->aflag][b & 3](val, next_eip);
2865 s->is_jmp = 1; 3143 s->is_jmp = 1;
2866 break; 3144 break;
2867 case 0x131: /* rdtsc */ 3145 case 0x131: /* rdtsc */
@@ -3203,8 +3481,8 @@ static uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; @@ -3203,8 +3481,8 @@ static uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
3203 3481
3204 /* return the next pc */ 3482 /* return the next pc */
3205 int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, 3483 int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
3206 - int *gen_code_size_ptr, uint8_t *pc_start,  
3207 - int flags) 3484 + int *gen_code_size_ptr,
  3485 + uint8_t *pc_start, uint8_t *cs_base, int flags)
3208 { 3486 {
3209 DisasContext dc1, *dc = &dc1; 3487 DisasContext dc1, *dc = &dc1;
3210 uint8_t *pc_ptr; 3488 uint8_t *pc_ptr;
@@ -3218,9 +3496,11 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, @@ -3218,9 +3496,11 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
3218 /* generate intermediate code */ 3496 /* generate intermediate code */
3219 3497
3220 dc->code32 = (flags >> GEN_FLAG_CODE32_SHIFT) & 1; 3498 dc->code32 = (flags >> GEN_FLAG_CODE32_SHIFT) & 1;
  3499 + dc->ss32 = (flags >> GEN_FLAG_SS32_SHIFT) & 1;
3221 dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1; 3500 dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;
3222 dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7; 3501 dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;
3223 dc->cc_op = CC_OP_DYNAMIC; 3502 dc->cc_op = CC_OP_DYNAMIC;
  3503 + dc->cs_base = cs_base;
3224 3504
3225 gen_opc_ptr = gen_opc_buf; 3505 gen_opc_ptr = gen_opc_buf;
3226 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; 3506 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
@@ -3242,7 +3522,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, @@ -3242,7 +3522,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
3242 gen_op_set_cc_op(dc->cc_op); 3522 gen_op_set_cc_op(dc->cc_op);
3243 if (dc->is_jmp != 1) { 3523 if (dc->is_jmp != 1) {
3244 /* we add an additionnal jmp to update the simulated PC */ 3524 /* we add an additionnal jmp to update the simulated PC */
3245 - gen_op_jmp_im(ret); 3525 + gen_op_jmp_im(ret - (unsigned long)dc->cs_base);
3246 } 3526 }
3247 *gen_opc_ptr = INDEX_op_end; 3527 *gen_opc_ptr = INDEX_op_end;
3248 3528
@@ -3258,11 +3538,11 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, @@ -3258,11 +3538,11 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
3258 disasm_info.arch = bfd_get_arch (abfd); 3538 disasm_info.arch = bfd_get_arch (abfd);
3259 disasm_info.mach = bfd_get_mach (abfd); 3539 disasm_info.mach = bfd_get_mach (abfd);
3260 #endif 3540 #endif
3261 -#ifdef WORDS_BIGENDIAN  
3262 - disasm_info.endian = BFD_ENDIAN_BIG;  
3263 -#else  
3264 disasm_info.endian = BFD_ENDIAN_LITTLE; 3541 disasm_info.endian = BFD_ENDIAN_LITTLE;
3265 -#endif 3542 + if (dc->code32)
  3543 + disasm_info.mach = bfd_mach_i386_i386;
  3544 + else
  3545 + disasm_info.mach = bfd_mach_i386_i8086;
3266 fprintf(logfile, "----------------\n"); 3546 fprintf(logfile, "----------------\n");
3267 fprintf(logfile, "IN:\n"); 3547 fprintf(logfile, "IN:\n");
3268 disasm_info.buffer = pc_start; 3548 disasm_info.buffer = pc_start;
@@ -3304,6 +3584,19 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, @@ -3304,6 +3584,19 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
3304 uint8_t *pc; 3584 uint8_t *pc;
3305 int count; 3585 int count;
3306 3586
  3587 + INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
  3588 +#if 0
  3589 + disasm_info.flavour = bfd_get_flavour (abfd);
  3590 + disasm_info.arch = bfd_get_arch (abfd);
  3591 + disasm_info.mach = bfd_get_mach (abfd);
  3592 +#endif
  3593 +#ifdef WORDS_BIGENDIAN
  3594 + disasm_info.endian = BFD_ENDIAN_BIG;
  3595 +#else
  3596 + disasm_info.endian = BFD_ENDIAN_LITTLE;
  3597 +#endif
  3598 + disasm_info.mach = bfd_mach_i386_i386;
  3599 +
3307 pc = gen_code_buf; 3600 pc = gen_code_buf;
3308 disasm_info.buffer = pc; 3601 disasm_info.buffer = pc;
3309 disasm_info.buffer_vma = (unsigned long)pc; 3602 disasm_info.buffer_vma = (unsigned long)pc;