Revision dab2ed99

b/TODO
1
- overrides/16bit for string ops
1 2
- optimize translated cache chaining (DLL PLT-like system)
2 3
- 64 bit syscalls
3 4
- signals
b/cpu-i386.h
141 141
typedef struct CPUX86State {
142 142
    /* standard registers */
143 143
    uint32_t regs[8];
144
    uint32_t pc; /* cs_case + eip value */
144
    uint32_t eip;
145 145
    uint32_t eflags;
146 146

  
147 147
    /* emulator internal eflags handling */
......
392 392

  
393 393
#define GEN_FLAG_CODE32_SHIFT 0
394 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 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 401
void cpu_x86_tblocks_init(void);
400 402

  
401 403
#endif /* CPU_I386_H */
b/exec-i386.c
38 38
#define CODE_GEN_HASH_SIZE     (1 << CODE_GEN_HASH_BITS)
39 39

  
40 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 43
    unsigned int flags; /* flags defining in which context the code was generated */
43 44
    uint8_t *tc_ptr;    /* pointer to the translated code */
44 45
    struct TranslationBlock *hash_next; /* next matching block */
......
140 141
/* find a translation block in the translation cache. If not found,
141 142
   allocate a new one */
142 143
static inline TranslationBlock *tb_find_and_alloc(unsigned long pc, 
144
                                                  unsigned long cs_base,
143 145
                                                  unsigned int flags)
144 146
{
145 147
    TranslationBlock **ptb, *tb;
......
151 153
        tb = *ptb;
152 154
        if (!tb)
153 155
            break;
154
        if (tb->pc == pc && tb->flags == flags)
156
        if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags)
155 157
            return tb;
156 158
        ptb = &tb->hash_next;
157 159
    }
......
161 163
    tb = &tbs[nb_tbs++];
162 164
    *ptb = tb;
163 165
    tb->pc = pc;
166
    tb->cs_base = cs_base;
164 167
    tb->flags = flags;
165 168
    tb->tc_ptr = NULL;
166 169
    tb->hash_next = NULL;
......
198 201
    int code_gen_size, ret;
199 202
    void (*gen_func)(void);
200 203
    TranslationBlock *tb;
201
    uint8_t *tc_ptr;
204
    uint8_t *tc_ptr, *cs_base, *pc;
202 205
    unsigned int flags;
203 206

  
204 207
    /* first we save global registers */
......
251 254
            /* we compute the CPU state. We assume it will not
252 255
               change during the whole generated block. */
253 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 258
            flags |= (((unsigned long)env->seg_cache[R_DS].base | 
255 259
                       (unsigned long)env->seg_cache[R_ES].base |
256 260
                       (unsigned long)env->seg_cache[R_SS].base) != 0) << 
257 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 266
            tc_ptr = tb->tc_ptr;
260 267
            if (!tb->tc_ptr) {
261 268
                /* if no translated code available, then translate it now */
262 269
                tc_ptr = code_gen_ptr;
263 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 272
                tb->tc_ptr = tc_ptr;
266 273
                code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
267 274
            }
b/exec-i386.h
111 111
#ifndef reg_EDI
112 112
#define EDI (env->regs[R_EDI])
113 113
#endif
114
#define PC  (env->pc)
114
#define EIP  (env->eip)
115 115
#define DF  (env->df)
116 116

  
117 117
#define CC_SRC (env->cc_src)
b/linux-user/main.c
179 179
    env->regs[R_EDI] = regs->edi;
180 180
    env->regs[R_EBP] = regs->ebp;
181 181
    env->regs[R_ESP] = regs->esp;
182
    env->pc = regs->eip;
182
    env->eip = regs->eip;
183 183

  
184 184
    /* linux segment setup */
185 185
    env->gdt.base = (void *)gdt_table;
......
198 198
        uint8_t *pc;
199 199
        
200 200
        err = cpu_x86_exec(env);
201
        pc = env->seg_cache[R_CS].base + env->eip;
201 202
        switch(err) {
202 203
        case EXCP0D_GPF:
203
            pc = (uint8_t *)env->pc;
204 204
            if (pc[0] == 0xcd && pc[1] == 0x80) {
205 205
                /* syscall */
206
                env->pc += 2;
206
                env->eip += 2;
207 207
                env->regs[R_EAX] = do_syscall(env, 
208 208
                                              env->regs[R_EAX], 
209 209
                                              env->regs[R_EBX],
......
219 219
        default:
220 220
        trap_error:
221 221
            fprintf(stderr, "0x%08lx: Unknown exception %d, aborting\n", 
222
                    (long)env->pc, err);
222
                    (long)pc, err);
223 223
            abort();
224 224
        }
225 225
    }
b/linux-user/syscall.c
53 53
#include <linux/cdrom.h>
54 54
#include <linux/hdreg.h>
55 55
#include <linux/soundcard.h>
56
#include <linux/dirent.h>
56 57

  
57 58
#include "gemu.h"
58 59

  
......
63 64
#define PAGE_MASK ~(PAGE_SIZE - 1)
64 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 67
//#include <linux/msdos_fs.h>
74 68
#define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct dirent [2])
75 69
#define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct dirent [2])
......
86 80
#define __NR_sys_statfs __NR_statfs
87 81
#define __NR_sys_fstatfs __NR_fstatfs
88 82
#define __NR_sys_getdents __NR_getdents
83
#define __NR_sys_getdents64 __NR_getdents64
89 84

  
90 85
#ifdef __NR_gettid
91 86
_syscall0(int, gettid)
......
97 92
_syscall1(int,sys_uname,struct new_utsname *,buf)
98 93
_syscall2(int,sys_getcwd1,char *,buf,size_t,size)
99 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 96
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
101 97
          loff_t *, res, uint, wh);
102 98
_syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf)
......
1005 1001
        ret = get_errno(setsid());
1006 1002
        break;
1007 1003
    case TARGET_NR_sigaction:
1008
#if 0
1004
#if 1
1009 1005
        {
1010 1006
            ret = 0;
1011 1007
        }
......
1336 1332
        {
1337 1333
            struct dirent *dirp = (void *)arg2;
1338 1334
            long count = arg3;
1335

  
1339 1336
            ret = get_errno(sys_getdents(arg1, dirp, count));
1340 1337
            if (!is_error(ret)) {
1341 1338
                struct dirent *de;
......
1355 1352
            }
1356 1353
        }
1357 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 1378
    case TARGET_NR__newselect:
1359 1379
        ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 
1360 1380
                        (void *)arg5);
......
1519 1539
    case TARGET_NR_pivot_root:
1520 1540
    case TARGET_NR_mincore:
1521 1541
    case TARGET_NR_madvise:
1522
    case TARGET_NR_getdents64:
1523 1542
        goto unimplemented;
1524 1543
#if TARGET_LONG_BITS == 32
1525 1544
    case TARGET_NR_fcntl64:
b/linux-user/syscall_defs.h
75 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 94
/* mostly generic signal stuff */
79 95
#define TARGET_SIG_DFL	((target_long)0)	/* default signal handling */
80 96
#define TARGET_SIG_IGN	((target_long)1)	/* ignore signal */
b/op-i386.c
464 464
    EDX = r;
465 465
}
466 466

  
467
/* constant load */
467
/* constant load & misc op */
468 468

  
469 469
void OPPROTO op_movl_T0_im(void)
470 470
{
471 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 489
void OPPROTO op_movl_T1_im(void)
475 490
{
476 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 504
void OPPROTO op_movl_A0_im(void)
480 505
{
481 506
    A0 = PARAM1;
......
574 599

  
575 600
void OPPROTO op_jmp_T0(void)
576 601
{
577
    PC = T0;
602
    EIP = T0;
578 603
}
579 604

  
580 605
void OPPROTO op_jmp_im(void)
581 606
{
582
    PC = PARAM1;
607
    EIP = PARAM1;
583 608
}
584 609

  
585 610
void OPPROTO op_int_im(void)
586 611
{
587
    PC = PARAM1;
612
    EIP = PARAM1;
588 613
    raise_exception(EXCP0D_GPF);
589 614
}
590 615

  
591 616
void OPPROTO op_int3(void)
592 617
{
593
    PC = PARAM1;
618
    EIP = PARAM1;
594 619
    raise_exception(EXCP03_INT3);
595 620
}
596 621

  
......
599 624
    int eflags;
600 625
    eflags = cc_table[CC_OP].compute_all();
601 626
    if (eflags & CC_O) {
602
        PC = PARAM1;
627
        EIP = PARAM1;
603 628
        raise_exception(EXCP04_INTO);
604 629
    } else {
605
        PC = PARAM2;
630
        EIP = PARAM2;
606 631
    }
607 632
}
608 633

  
......
665 690
}
666 691

  
667 692
/* push/pop */
668
/* XXX: add 16 bit operand/16 bit seg variants */
669 693

  
670 694
void op_pushl_T0(void)
671 695
{
......
676 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 714
    uint32_t offset;
682 715
    offset = ESP - 4;
683
    stl((void *)offset, T1);
716
    stl(env->seg_cache[R_SS].base + offset, T0);
684 717
    /* modify ESP after to handle exceptions correctly */
685 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 749
void op_popl_T0(void)
689 750
{
690 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 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 799
void op_addl_ESP_im(void)
695 800
{
696 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 809
/* rdtsc */
......
988 1015
    int eflags;
989 1016
    eflags = cc_table[CC_OP].compute_all();
990 1017
    if (eflags & CC_O)
991
        PC = PARAM1;
1018
        EIP = PARAM1;
992 1019
    else
993
        PC = PARAM2;
1020
        EIP = PARAM2;
994 1021
    FORCE_RET();
995 1022
}
996 1023

  
997 1024
void OPPROTO op_jb_cc(void)
998 1025
{
999 1026
    if (cc_table[CC_OP].compute_c())
1000
        PC = PARAM1;
1027
        EIP = PARAM1;
1001 1028
    else
1002
        PC = PARAM2;
1029
        EIP = PARAM2;
1003 1030
    FORCE_RET();
1004 1031
}
1005 1032

  
......
1008 1035
    int eflags;
1009 1036
    eflags = cc_table[CC_OP].compute_all();
1010 1037
    if (eflags & CC_Z)
1011
        PC = PARAM1;
1038
        EIP = PARAM1;
1012 1039
    else
1013
        PC = PARAM2;
1040
        EIP = PARAM2;
1014 1041
    FORCE_RET();
1015 1042
}
1016 1043

  
......
1019 1046
    int eflags;
1020 1047
    eflags = cc_table[CC_OP].compute_all();
1021 1048
    if (eflags & (CC_Z | CC_C))
1022
        PC = PARAM1;
1049
        EIP = PARAM1;
1023 1050
    else
1024
        PC = PARAM2;
1051
        EIP = PARAM2;
1025 1052
    FORCE_RET();
1026 1053
}
1027 1054

  
......
1030 1057
    int eflags;
1031 1058
    eflags = cc_table[CC_OP].compute_all();
1032 1059
    if (eflags & CC_S)
1033
        PC = PARAM1;
1060
        EIP = PARAM1;
1034 1061
    else
1035
        PC = PARAM2;
1062
        EIP = PARAM2;
1036 1063
    FORCE_RET();
1037 1064
}
1038 1065

  
......
1041 1068
    int eflags;
1042 1069
    eflags = cc_table[CC_OP].compute_all();
1043 1070
    if (eflags & CC_P)
1044
        PC = PARAM1;
1071
        EIP = PARAM1;
1045 1072
    else
1046
        PC = PARAM2;
1073
        EIP = PARAM2;
1047 1074
    FORCE_RET();
1048 1075
}
1049 1076

  
......
1052 1079
    int eflags;
1053 1080
    eflags = cc_table[CC_OP].compute_all();
1054 1081
    if ((eflags ^ (eflags >> 4)) & 0x80)
1055
        PC = PARAM1;
1082
        EIP = PARAM1;
1056 1083
    else
1057
        PC = PARAM2;
1084
        EIP = PARAM2;
1058 1085
    FORCE_RET();
1059 1086
}
1060 1087

  
......
1063 1090
    int eflags;
1064 1091
    eflags = cc_table[CC_OP].compute_all();
1065 1092
    if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z))
1066
        PC = PARAM1;
1093
        EIP = PARAM1;
1067 1094
    else
1068
        PC = PARAM2;
1095
        EIP = PARAM2;
1069 1096
    FORCE_RET();
1070 1097
}
1071 1098

  
b/opc-i386.h
202 202
DEF(divl_EAX_T0)
203 203
DEF(idivl_EAX_T0)
204 204
DEF(movl_T0_im)
205
DEF(addl_T0_im)
206
DEF(andl_T0_ffff)
207
DEF(movl_T0_T1)
205 208
DEF(movl_T1_im)
209
DEF(addl_T1_im)
210
DEF(movl_T1_A0)
206 211
DEF(movl_A0_im)
207 212
DEF(addl_A0_im)
208 213
DEF(andl_A0_ffff)
......
398 403
DEF(movslq_EDX_EAX)
399 404
DEF(movswl_DX_AX)
400 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 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 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 423
DEF(rdtsc)
410 424
DEF(aam)
411 425
DEF(aad)
b/ops_template.h
214 214
    src2 = CC_SRC - CC_DST;
215 215

  
216 216
    if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
217
        PC = PARAM1;
217
        EIP = PARAM1;
218 218
    else
219
        PC = PARAM2;
219
        EIP = PARAM2;
220 220
    FORCE_RET();
221 221
}
222 222

  
223 223
void OPPROTO glue(op_jz_sub, SUFFIX)(void)
224 224
{
225 225
    if ((DATA_TYPE)CC_DST == 0)
226
        PC = PARAM1;
226
        EIP = PARAM1;
227 227
    else
228
        PC = PARAM2;
228
        EIP = PARAM2;
229 229
    FORCE_RET();
230 230
}
231 231

  
......
236 236
    src2 = CC_SRC - CC_DST;
237 237

  
238 238
    if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
239
        PC = PARAM1;
239
        EIP = PARAM1;
240 240
    else
241
        PC = PARAM2;
241
        EIP = PARAM2;
242 242
    FORCE_RET();
243 243
}
244 244

  
245 245
void OPPROTO glue(op_js_sub, SUFFIX)(void)
246 246
{
247 247
    if (CC_DST & SIGN_MASK)
248
        PC = PARAM1;
248
        EIP = PARAM1;
249 249
    else
250
        PC = PARAM2;
250
        EIP = PARAM2;
251 251
    FORCE_RET();
252 252
}
253 253

  
......
258 258
    src2 = CC_SRC - CC_DST;
259 259

  
260 260
    if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
261
        PC = PARAM1;
261
        EIP = PARAM1;
262 262
    else
263
        PC = PARAM2;
263
        EIP = PARAM2;
264 264
    FORCE_RET();
265 265
}
266 266

  
......
271 271
    src2 = CC_SRC - CC_DST;
272 272

  
273 273
    if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
274
        PC = PARAM1;
274
        EIP = PARAM1;
275 275
    else
276
        PC = PARAM2;
276
        EIP = PARAM2;
277 277
    FORCE_RET();
278 278
}
279 279

  
......
289 289
    tmp = (ECX - 1) & DATA_MASK;
290 290
    ECX = (ECX & ~DATA_MASK) | tmp;
291 291
    if (tmp != 0 && !(eflags & CC_Z))
292
        PC = PARAM1;
292
        EIP = PARAM1;
293 293
    else
294
        PC = PARAM2;
294
        EIP = PARAM2;
295 295
    FORCE_RET();
296 296
}
297 297

  
......
303 303
    tmp = (ECX - 1) & DATA_MASK;
304 304
    ECX = (ECX & ~DATA_MASK) | tmp;
305 305
    if (tmp != 0 && (eflags & CC_Z))
306
        PC = PARAM1;
306
        EIP = PARAM1;
307 307
    else
308
        PC = PARAM2;
308
        EIP = PARAM2;
309 309
    FORCE_RET();
310 310
}
311 311

  
......
315 315
    tmp = (ECX - 1) & DATA_MASK;
316 316
    ECX = (ECX & ~DATA_MASK) | tmp;
317 317
    if (tmp != 0)
318
        PC = PARAM1;
318
        EIP = PARAM1;
319 319
    else
320
        PC = PARAM2;
320
        EIP = PARAM2;
321 321
    FORCE_RET();
322 322
}
323 323

  
324 324
void OPPROTO glue(op_jecxz, SUFFIX)(void)
325 325
{
326 326
    if ((DATA_TYPE)ECX == 0)
327
        PC = PARAM1;
327
        EIP = PARAM1;
328 328
    else
329
        PC = PARAM2;
329
        EIP = PARAM2;
330 330
    FORCE_RET();
331 331
}
332 332

  
b/translate-i386.c
92 92
    /* current insn context */
93 93
    int prefix;
94 94
    int aflag, dflag;
95
    uint8_t *pc; /* current pc */
95
    uint8_t *pc; /* pc = eip + cs_base */
96 96
    int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
97 97
                   static state change (stop translation) */
98 98
    /* current block context */
99
    uint8_t *cs_base; /* base of CS segment */
99 100
    int code32; /* 32 bit code segment */
101
    int ss32;   /* 32 bit stack segment */
100 102
    int cc_op;  /* current CC operation */
101 103
    int addseg; /* non zero if either DS/ES/SS have a non zero base */
102 104
    int f_st;   /* currently unused */
......
1051 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 1058
    int inv, jcc_op;
1057 1059
    GenOpFunc2 *func;
......
1112 1114
        break;
1113 1115
    }
1114 1116
    if (!inv) {
1115
        func(val, (long)s->pc);
1117
        func(val, next_eip);
1116 1118
    } else {
1117
        func((long)s->pc, val);
1119
        func(next_eip, val);
1118 1120
    }
1119 1121
}
1120 1122

  
......
1176 1178
}
1177 1179

  
1178 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 1183
    gen_op_movl_seg_T0(seg_reg);
1182 1184
    if (!s->addseg && seg_reg < R_FS)
......
1184 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 1331
/* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
1188 1332
   is set to true if the instruction sets the PC (last instruction of
1189 1333
   a basic block) */
......
1192 1336
    int b, prefixes, aflag, dflag;
1193 1337
    int shift, ot;
1194 1338
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
1339
    unsigned int next_eip;
1195 1340

  
1196 1341
    s->pc = pc_start;
1197 1342
    prefixes = 0;
......
1492 1637
        }
1493 1638
        if (mod != 3) {
1494 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 1642
        } else {
1497 1643
            gen_op_mov_TN_reg[ot][0][rm]();
1498 1644
        }
......
1513 1659
                gen_op_mov_reg_T0[ot][rm]();
1514 1660
            break;
1515 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 1684
            gen_op_jmp_T0();
1519 1685
            s->is_jmp = 1;
1520 1686
            break;
1521 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 1699
            gen_op_jmp_T0();
1523 1700
            s->is_jmp = 1;
1524 1701
            break;
1525 1702
        case 6: /* push Ev */
1526
            gen_op_pushl_T0();
1703
            gen_push_T0(s);
1527 1704
            break;
1528 1705
        default:
1529 1706
            goto illegal_op;
......
1653 1830
        /* push/pop */
1654 1831
    case 0x50 ... 0x57: /* push */
1655 1832
        gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
1656
        gen_op_pushl_T0();
1833
        gen_push_T0(s);
1657 1834
        break;
1658 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 1840
        break;
1662 1841
    case 0x60: /* pusha */
1663
        if (s->dflag)
1664
            gen_op_pushal();
1665
        else
1666
            gen_op_pushaw();
1842
        gen_pusha(s);
1667 1843
        break;
1668 1844
    case 0x61: /* popa */
1669
        if (s->dflag)
1670
            gen_op_popal();
1671
        else
1672
            gen_op_popaw();
1845
        gen_popa(s);
1673 1846
        break;
1674 1847
    case 0x68: /* push Iv */
1675 1848
    case 0x6a:
......
1679 1852
        else
1680 1853
            val = (int8_t)insn_get(s, OT_BYTE);
1681 1854
        gen_op_movl_T0_im(val);
1682
        gen_op_pushl_T0();
1855
        gen_push_T0(s);
1683 1856
        break;
1684 1857
    case 0x8f: /* pop Ev */
1685 1858
        ot = dflag ? OT_LONG : OT_WORD;
1686 1859
        modrm = ldub(s->pc++);
1687
        gen_op_popl_T0();
1860
        gen_pop_T0(s);
1688 1861
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1862
        gen_pop_update(s);
1689 1863
        break;
1690 1864
    case 0xc8: /* enter */
1691 1865
        {
......
1693 1867
            val = lduw(s->pc);
1694 1868
            s->pc += 2;
1695 1869
            level = ldub(s->pc++);
1696
            level &= 0x1f;
1697
            gen_op_enterl(val, level);
1870
            gen_enter(s, val, level);
1698 1871
        }
1699 1872
        break;
1700 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 1886
        break;
1706 1887
    case 0x06: /* push es */
1707 1888
    case 0x0e: /* push cs */
1708 1889
    case 0x16: /* push ss */
1709 1890
    case 0x1e: /* push ds */
1710 1891
        gen_op_movl_T0_seg(b >> 3);
1711
        gen_op_pushl_T0();
1892
        gen_push_T0(s);
1712 1893
        break;
1713 1894
    case 0x1a0: /* push fs */
1714 1895
    case 0x1a8: /* push gs */
1715 1896
        gen_op_movl_T0_seg(((b >> 3) & 7) + R_FS);
1716
        gen_op_pushl_T0();
1897
        gen_push_T0(s);
1717 1898
        break;
1718 1899
    case 0x07: /* pop es */
1719 1900
    case 0x17: /* pop ss */
1720 1901
    case 0x1f: /* pop ds */
1721
        gen_op_popl_T0();
1902
        gen_pop_T0(s);
1722 1903
        gen_movl_seg_T0(s, b >> 3);
1904
        gen_pop_update(s);
1723 1905
        break;
1724 1906
    case 0x1a1: /* pop fs */
1725 1907
    case 0x1a9: /* pop gs */
1726
        gen_op_popl_T0();
1908
        gen_pop_T0(s);
1727 1909
        gen_movl_seg_T0(s, ((b >> 3) & 7) + R_FS);
1910
        gen_pop_update(s);
1728 1911
        break;
1729 1912

  
1730 1913
        /**************************/
......
1775 1958
        modrm = ldub(s->pc++);
1776 1959
        reg = (modrm >> 3) & 7;
1777 1960
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1778
        if (reg >= 6)
1961
        if (reg >= 6 || reg == R_CS)
1779 1962
            goto illegal_op;
1780 1963
        gen_movl_seg_T0(s, reg);
1781 1964
        break;
......
2585 2768
        /************************/
2586 2769
        /* control */
2587 2770
    case 0xc2: /* ret im */
2588
        /* XXX: handle stack pop ? */
2589 2771
        val = ldsw(s->pc);
2590 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 2780
        gen_op_jmp_T0();
2594 2781
        s->is_jmp = 1;
2595 2782
        break;
2596 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 2788
        gen_op_jmp_T0();
2599 2789
        s->is_jmp = 1;
2600 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 2822
        s->is_jmp = 1;
2608 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 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 2867
        gen_op_jmp_im(val);
2613 2868
        s->is_jmp = 1;
2614 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 2885
    case 0xeb: /* jmp Jb */
2616 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 2890
        gen_op_jmp_im(val);
2619 2891
        s->is_jmp = 1;
2620 2892
        break;
2621 2893
    case 0x70 ... 0x7f: /* jcc Jb */
2622 2894
        val = (int8_t)insn_get(s, OT_BYTE);
2623
        val += (long)s->pc;
2624 2895
        goto do_jcc;
2625 2896
    case 0x180 ... 0x18f: /* jcc Jv */
2626 2897
        if (dflag) {
......
2628 2899
        } else {
2629 2900
            val = (int16_t)insn_get(s, OT_WORD); 
2630 2901
        }
2631
        val += (long)s->pc; /* XXX: fix 16 bit wrap */
2632 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 2908
        s->is_jmp = 1;
2635 2909
        break;
2636 2910

  
......
2661 2935
        if (s->cc_op != CC_OP_DYNAMIC)
2662 2936
            gen_op_set_cc_op(s->cc_op);
2663 2937
        gen_op_movl_T0_eflags();
2664
        gen_op_pushl_T0();
2938
        gen_push_T0(s);
2665 2939
        break;
2666 2940
    case 0x9d: /* popf */
2667
        gen_op_popl_T0();
2941
        gen_pop_T0(s);
2668 2942
        gen_op_movl_eflags_T0();
2943
        gen_pop_update(s);
2669 2944
        s->cc_op = CC_OP_EFLAGS;
2670 2945
        break;
2671 2946
    case 0x9e: /* sahf */
......
2860 3135
    case 0xe2: /* loop */
2861 3136
    case 0xe3: /* jecxz */
2862 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 3143
        s->is_jmp = 1;
2866 3144
        break;
2867 3145
    case 0x131: /* rdtsc */
......
3203 3481

  
3204 3482
/* return the next pc */
3205 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 3487
    DisasContext dc1, *dc = &dc1;
3210 3488
    uint8_t *pc_ptr;
......
3218 3496
    /* generate intermediate code */
3219 3497

  
3220 3498
    dc->code32 = (flags >> GEN_FLAG_CODE32_SHIFT) & 1;
3499
    dc->ss32 = (flags >> GEN_FLAG_SS32_SHIFT) & 1;
3221 3500
    dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;
3222 3501
    dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;
3223 3502
    dc->cc_op = CC_OP_DYNAMIC;
3503
    dc->cs_base = cs_base;
3224 3504

  
3225 3505
    gen_opc_ptr = gen_opc_buf;
3226 3506
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
......
3242 3522
        gen_op_set_cc_op(dc->cc_op);
3243 3523
    if (dc->is_jmp != 1) {
3244 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 3527
    *gen_opc_ptr = INDEX_op_end;
3248 3528

  
......
3258 3538
        disasm_info.arch = bfd_get_arch (abfd);
3259 3539
        disasm_info.mach = bfd_get_mach (abfd);
3260 3540
#endif
3261
#ifdef WORDS_BIGENDIAN
3262
        disasm_info.endian = BFD_ENDIAN_BIG;
3263
#else
3264 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 3546
        fprintf(logfile, "----------------\n");
3267 3547
        fprintf(logfile, "IN:\n");
3268 3548
        disasm_info.buffer = pc_start;
......
3304 3584
        uint8_t *pc;
3305 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 3600
        pc = gen_code_buf;
3308 3601
        disasm_info.buffer = pc;
3309 3602
        disasm_info.buffer_vma = (unsigned long)pc;

Also available in: Unified diff