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