120 |
TranslationBlock *tb, **ptb; |
TranslationBlock *tb, **ptb; |
121 |
uint8_t *tc_ptr, *cs_base, *pc; |
uint8_t *tc_ptr, *cs_base, *pc; |
122 |
unsigned int flags; |
unsigned int flags; |
123 |
|
|
124 |
/* first we save global registers */ |
/* first we save global registers */ |
125 |
saved_T0 = T0; |
saved_T0 = T0; |
126 |
saved_T1 = T1; |
saved_T1 = T1; |
169 |
|
|
170 |
/* prepare setjmp context for exception handling */ |
/* prepare setjmp context for exception handling */ |
171 |
if (setjmp(env->jmp_env) == 0) { |
if (setjmp(env->jmp_env) == 0) { |
172 |
|
T0 = 0; /* force lookup of first TB */ |
173 |
for(;;) { |
for(;;) { |
174 |
if (env->interrupt_request) { |
if (env->interrupt_request) { |
175 |
raise_exception(EXCP_INTERRUPT); |
raise_exception(EXCP_INTERRUPT); |
210 |
flags |= (env->eflags & TF_MASK) << (GEN_FLAG_TF_SHIFT - 8); |
flags |= (env->eflags & TF_MASK) << (GEN_FLAG_TF_SHIFT - 8); |
211 |
cs_base = env->seg_cache[R_CS].base; |
cs_base = env->seg_cache[R_CS].base; |
212 |
pc = cs_base + env->eip; |
pc = cs_base + env->eip; |
213 |
|
spin_lock(&tb_lock); |
214 |
tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
215 |
flags); |
flags); |
216 |
if (!tb) { |
if (!tb) { |
217 |
/* if no translated code available, then translate it now */ |
/* if no translated code available, then translate it now */ |
218 |
/* very inefficient but safe: we lock all the cpus |
tb = tb_alloc((unsigned long)pc); |
219 |
when generating code */ |
if (!tb) { |
220 |
spin_lock(&tb_lock); |
/* flush must be done */ |
221 |
|
tb_flush(); |
222 |
|
/* cannot fail at this point */ |
223 |
|
tb = tb_alloc((unsigned long)pc); |
224 |
|
/* don't forget to invalidate previous TB info */ |
225 |
|
ptb = &tb_hash[tb_hash_func((unsigned long)pc)]; |
226 |
|
T0 = 0; |
227 |
|
} |
228 |
tc_ptr = code_gen_ptr; |
tc_ptr = code_gen_ptr; |
229 |
|
tb->tc_ptr = tc_ptr; |
230 |
ret = cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE, |
ret = cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE, |
231 |
&code_gen_size, pc, cs_base, flags, |
&code_gen_size, pc, cs_base, flags, |
232 |
&code_size); |
&code_size, tb); |
233 |
/* if invalid instruction, signal it */ |
/* if invalid instruction, signal it */ |
234 |
if (ret != 0) { |
if (ret != 0) { |
235 |
|
/* NOTE: the tb is allocated but not linked, so we |
236 |
|
can leave it */ |
237 |
spin_unlock(&tb_lock); |
spin_unlock(&tb_lock); |
238 |
raise_exception(EXCP06_ILLOP); |
raise_exception(EXCP06_ILLOP); |
239 |
} |
} |
|
tb = tb_alloc((unsigned long)pc, code_size); |
|
240 |
*ptb = tb; |
*ptb = tb; |
241 |
|
tb->size = code_size; |
242 |
tb->cs_base = (unsigned long)cs_base; |
tb->cs_base = (unsigned long)cs_base; |
243 |
tb->flags = flags; |
tb->flags = flags; |
|
tb->tc_ptr = tc_ptr; |
|
244 |
tb->hash_next = NULL; |
tb->hash_next = NULL; |
245 |
|
tb_link(tb); |
246 |
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
|
spin_unlock(&tb_lock); |
|
247 |
} |
} |
248 |
#ifdef DEBUG_EXEC |
#ifdef DEBUG_EXEC |
249 |
if (loglevel) { |
if (loglevel) { |
252 |
lookup_symbol((void *)tb->pc)); |
lookup_symbol((void *)tb->pc)); |
253 |
} |
} |
254 |
#endif |
#endif |
255 |
/* execute the generated code */ |
|
256 |
|
/* see if we can patch the calling TB */ |
257 |
|
if (T0 != 0 && !(env->eflags & TF_MASK)) { |
258 |
|
tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); |
259 |
|
} |
260 |
tc_ptr = tb->tc_ptr; |
tc_ptr = tb->tc_ptr; |
261 |
|
spin_unlock(&tb_lock); |
262 |
|
|
263 |
|
/* execute the generated code */ |
264 |
gen_func = (void *)tc_ptr; |
gen_func = (void *)tc_ptr; |
265 |
#ifdef __sparc__ |
#ifdef __sparc__ |
266 |
__asm__ __volatile__("call %0\n\t" |
__asm__ __volatile__("call %0\n\t" |
267 |
" mov %%o7,%%i0" |
" mov %%o7,%%i0" |
268 |
: /* no outputs */ |
: /* no outputs */ |
269 |
: "r" (gen_func) |
: "r" (gen_func) |
270 |
: "i0", "i1", "i2", "i3", "i4", "i5"); |
: "i0", "i1", "i2", "i3", "i4", "i5"); |
271 |
#else |
#else |
272 |
gen_func(); |
gen_func(); |