Revision 6dbad63e exec-i386.c

b/exec-i386.c
36 36
#define CODE_GEN_MAX_BLOCKS    (CODE_GEN_BUFFER_SIZE / 64)
37 37
#define CODE_GEN_HASH_BITS     15
38 38
#define CODE_GEN_HASH_SIZE     (1 << CODE_GEN_HASH_BITS)
39

  
39 40
typedef struct TranslationBlock {
40 41
    unsigned long pc;   /* simulated PC corresponding to this block */
42
    unsigned int flags; /* flags defining in which context the code was generated */
41 43
    uint8_t *tc_ptr;    /* pointer to the translated code */
42 44
    struct TranslationBlock *hash_next; /* next matching block */
43 45
} TranslationBlock;
......
137 139

  
138 140
/* find a translation block in the translation cache. If not found,
139 141
   allocate a new one */
140
static inline TranslationBlock *tb_find_and_alloc(unsigned long pc)
142
static inline TranslationBlock *tb_find_and_alloc(unsigned long pc, 
143
                                                  unsigned int flags)
141 144
{
142 145
    TranslationBlock **ptb, *tb;
143 146
    unsigned int h;
......
148 151
        tb = *ptb;
149 152
        if (!tb)
150 153
            break;
151
        if (tb->pc == pc)
154
        if (tb->pc == pc && tb->flags == flags)
152 155
            return tb;
153 156
        ptb = &tb->hash_next;
154 157
    }
......
158 161
    tb = &tbs[nb_tbs++];
159 162
    *ptb = tb;
160 163
    tb->pc = pc;
164
    tb->flags = flags;
161 165
    tb->tc_ptr = NULL;
162 166
    tb->hash_next = NULL;
163 167
    return tb;
......
171 175
    void (*gen_func)(void);
172 176
    TranslationBlock *tb;
173 177
    uint8_t *tc_ptr;
174
    
178
    unsigned int flags;
179

  
175 180
    /* first we save global registers */
176 181
    saved_T0 = T0;
177 182
    saved_T1 = T1;
......
187 192
                cpu_x86_dump_state();
188 193
            }
189 194
#endif
190
            tb = tb_find_and_alloc((unsigned long)env->pc);
195
            /* we compute the CPU state. We assume it will not
196
               change during the whole generated block. */
197
            flags = env->seg_cache[R_CS].seg_32bit << GEN_FLAG_CODE32_SHIFT;
198
            flags |= (((unsigned long)env->seg_cache[R_DS].base | 
199
                       (unsigned long)env->seg_cache[R_ES].base |
200
                       (unsigned long)env->seg_cache[R_SS].base) != 0) << 
201
                GEN_FLAG_ADDSEG_SHIFT;
202
            tb = tb_find_and_alloc((unsigned long)env->pc, flags);
191 203
            tc_ptr = tb->tc_ptr;
192 204
            if (!tb->tc_ptr) {
193 205
                /* if no translated code available, then translate it now */
194 206
                tc_ptr = code_gen_ptr;
195 207
                cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE, 
196
                                 &code_gen_size, (uint8_t *)env->pc);
208
                                 &code_gen_size, (uint8_t *)env->pc, flags);
197 209
                tb->tc_ptr = tc_ptr;
198 210
                code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
199 211
            }
......
211 223
    env = saved_env;
212 224
    return ret;
213 225
}
226

  
227
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
228
{
229
    CPUX86State *saved_env;
230

  
231
    saved_env = env;
232
    env = s;
233
    load_seg(seg_reg, selector);
234
    env = saved_env;
235
}

Also available in: Unified diff