Revision dab2ed99 exec-i386.c

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
            }

Also available in: Unified diff