Revision c27004ec cpu-exec.c
b/cpu-exec.c | ||
---|---|---|
106 | 106 |
int code_gen_size, ret, interrupt_request; |
107 | 107 |
void (*gen_func)(void); |
108 | 108 |
TranslationBlock *tb, **ptb; |
109 |
uint8_t *tc_ptr, *cs_base, *pc; |
|
109 |
target_ulong cs_base, pc; |
|
110 |
uint8_t *tc_ptr; |
|
110 | 111 |
unsigned int flags; |
111 | 112 |
|
112 | 113 |
/* first we save global registers */ |
114 |
saved_env = env; |
|
115 |
env = env1; |
|
113 | 116 |
saved_T0 = T0; |
114 | 117 |
saved_T1 = T1; |
115 | 118 |
saved_T2 = T2; |
116 |
saved_env = env; |
|
117 |
env = env1; |
|
118 | 119 |
#ifdef __sparc__ |
119 | 120 |
/* we also save i7 because longjmp may not restore it */ |
120 | 121 |
asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); |
... | ... | |
285 | 286 |
} |
286 | 287 |
} |
287 | 288 |
#ifdef DEBUG_EXEC |
288 |
if (loglevel & CPU_LOG_EXEC) {
|
|
289 |
if ((loglevel & CPU_LOG_EXEC)) {
|
|
289 | 290 |
#if defined(TARGET_I386) |
290 | 291 |
/* restore flags in standard format */ |
291 | 292 |
env->regs[R_EAX] = EAX; |
... | ... | |
323 | 324 |
#elif defined(TARGET_ARM) |
324 | 325 |
flags = 0; |
325 | 326 |
cs_base = 0; |
326 |
pc = (uint8_t *)env->regs[15];
|
|
327 |
pc = env->regs[15]; |
|
327 | 328 |
#elif defined(TARGET_SPARC) |
328 | 329 |
flags = 0; |
329 |
cs_base = (uint8_t *)env->npc;
|
|
330 |
pc = (uint8_t *) env->pc;
|
|
330 |
cs_base = env->npc; |
|
331 |
pc = env->pc; |
|
331 | 332 |
#elif defined(TARGET_PPC) |
332 | 333 |
flags = 0; |
333 | 334 |
cs_base = 0; |
334 |
pc = (uint8_t *)env->nip;
|
|
335 |
pc = env->nip; |
|
335 | 336 |
#else |
336 | 337 |
#error unsupported CPU |
337 | 338 |
#endif |
338 |
tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base,
|
|
339 |
tb = tb_find(&ptb, pc, cs_base,
|
|
339 | 340 |
flags); |
340 | 341 |
if (!tb) { |
341 | 342 |
TranslationBlock **ptb1; |
... | ... | |
350 | 351 |
regs_to_env(); /* XXX: do it just before cpu_gen_code() */ |
351 | 352 |
|
352 | 353 |
/* find translated block using physical mappings */ |
353 |
phys_pc = get_phys_addr_code(env, (unsigned long)pc);
|
|
354 |
phys_pc = get_phys_addr_code(env, pc); |
|
354 | 355 |
phys_page1 = phys_pc & TARGET_PAGE_MASK; |
355 | 356 |
phys_page2 = -1; |
356 | 357 |
h = tb_phys_hash_func(phys_pc); |
... | ... | |
359 | 360 |
tb = *ptb1; |
360 | 361 |
if (!tb) |
361 | 362 |
goto not_found; |
362 |
if (tb->pc == (unsigned long)pc &&
|
|
363 |
if (tb->pc == pc && |
|
363 | 364 |
tb->page_addr[0] == phys_page1 && |
364 |
tb->cs_base == (unsigned long)cs_base &&
|
|
365 |
tb->cs_base == cs_base && |
|
365 | 366 |
tb->flags == flags) { |
366 | 367 |
/* check next page if needed */ |
367 | 368 |
if (tb->page_addr[1] != -1) { |
368 |
virt_page2 = ((unsigned long)pc & TARGET_PAGE_MASK) +
|
|
369 |
virt_page2 = (pc & TARGET_PAGE_MASK) + |
|
369 | 370 |
TARGET_PAGE_SIZE; |
370 | 371 |
phys_page2 = get_phys_addr_code(env, virt_page2); |
371 | 372 |
if (tb->page_addr[1] == phys_page2) |
... | ... | |
378 | 379 |
} |
379 | 380 |
not_found: |
380 | 381 |
/* if no translated code available, then translate it now */ |
381 |
tb = tb_alloc((unsigned long)pc);
|
|
382 |
tb = tb_alloc(pc); |
|
382 | 383 |
if (!tb) { |
383 | 384 |
/* flush must be done */ |
384 | 385 |
tb_flush(env); |
385 | 386 |
/* cannot fail at this point */ |
386 |
tb = tb_alloc((unsigned long)pc);
|
|
387 |
tb = tb_alloc(pc); |
|
387 | 388 |
/* don't forget to invalidate previous TB info */ |
388 |
ptb = &tb_hash[tb_hash_func((unsigned long)pc)];
|
|
389 |
ptb = &tb_hash[tb_hash_func(pc)]; |
|
389 | 390 |
T0 = 0; |
390 | 391 |
} |
391 | 392 |
tc_ptr = code_gen_ptr; |
392 | 393 |
tb->tc_ptr = tc_ptr; |
393 |
tb->cs_base = (unsigned long)cs_base;
|
|
394 |
tb->cs_base = cs_base; |
|
394 | 395 |
tb->flags = flags; |
395 | 396 |
cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size); |
396 | 397 |
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
397 | 398 |
|
398 | 399 |
/* check next page if needed */ |
399 |
virt_page2 = ((unsigned long)pc + tb->size - 1) & TARGET_PAGE_MASK;
|
|
400 |
virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK; |
|
400 | 401 |
phys_page2 = -1; |
401 |
if (((unsigned long)pc & TARGET_PAGE_MASK) != virt_page2) {
|
|
402 |
if ((pc & TARGET_PAGE_MASK) != virt_page2) { |
|
402 | 403 |
phys_page2 = get_phys_addr_code(env, virt_page2); |
403 | 404 |
} |
404 | 405 |
tb_link_phys(tb, phys_pc, phys_page2); |
... | ... | |
408 | 409 |
/* as some TB could have been invalidated because |
409 | 410 |
of memory exceptions while generating the code, we |
410 | 411 |
must recompute the hash index here */ |
411 |
ptb = &tb_hash[tb_hash_func((unsigned long)pc)];
|
|
412 |
ptb = &tb_hash[tb_hash_func(pc)]; |
|
412 | 413 |
while (*ptb != NULL) |
413 | 414 |
ptb = &(*ptb)->hash_next; |
414 | 415 |
T0 = 0; |
... | ... | |
420 | 421 |
spin_unlock(&tb_lock); |
421 | 422 |
} |
422 | 423 |
#ifdef DEBUG_EXEC |
423 |
if (loglevel & CPU_LOG_EXEC) {
|
|
424 |
fprintf(logfile, "Trace 0x%08lx [0x%08lx] %s\n",
|
|
425 |
(long)tb->tc_ptr, (long)tb->pc,
|
|
426 |
lookup_symbol((void *)tb->pc));
|
|
424 |
if ((loglevel & CPU_LOG_EXEC) && (env->hflags & HF_LMA_MASK)) {
|
|
425 |
fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
|
|
426 |
(long)tb->tc_ptr, tb->pc, |
|
427 |
lookup_symbol(tb->pc)); |
|
427 | 428 |
} |
428 | 429 |
#endif |
429 | 430 |
#ifdef __sparc__ |
430 | 431 |
T0 = tmp_T0; |
431 | 432 |
#endif |
432 | 433 |
/* see if we can patch the calling TB. */ |
433 |
if (T0 != 0 |
|
434 |
{ |
|
435 |
if (T0 != 0 |
|
434 | 436 |
#if defined(TARGET_I386) && defined(USE_CODE_COPY) |
435 | 437 |
&& (tb->cflags & CF_CODE_COPY) == |
436 | 438 |
(((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY) |
437 | 439 |
#endif |
438 | 440 |
) { |
439 | 441 |
spin_lock(&tb_lock); |
440 |
tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); |
|
442 |
tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb);
|
|
441 | 443 |
#if defined(USE_CODE_COPY) |
442 | 444 |
/* propagates the FP use info */ |
443 | 445 |
((TranslationBlock *)(T0 & ~3))->cflags |= |
... | ... | |
445 | 447 |
#endif |
446 | 448 |
spin_unlock(&tb_lock); |
447 | 449 |
} |
450 |
} |
|
448 | 451 |
tc_ptr = tb->tc_ptr; |
449 | 452 |
env->current_tb = tb; |
450 | 453 |
/* execute the generated code */ |
... | ... | |
631 | 634 |
if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { |
632 | 635 |
selector &= 0xffff; |
633 | 636 |
cpu_x86_load_seg_cache(env, seg_reg, selector, |
634 |
(uint8_t *)(selector << 4), 0xffff, 0);
|
|
637 |
(selector << 4), 0xffff, 0); |
|
635 | 638 |
} else { |
636 | 639 |
load_seg(seg_reg, selector); |
637 | 640 |
} |
... | ... | |
645 | 648 |
saved_env = env; |
646 | 649 |
env = s; |
647 | 650 |
|
648 |
helper_fsave(ptr, data32); |
|
651 |
helper_fsave((target_ulong)ptr, data32);
|
|
649 | 652 |
|
650 | 653 |
env = saved_env; |
651 | 654 |
} |
... | ... | |
657 | 660 |
saved_env = env; |
658 | 661 |
env = s; |
659 | 662 |
|
660 |
helper_frstor(ptr, data32); |
|
663 |
helper_frstor((target_ulong)ptr, data32);
|
|
661 | 664 |
|
662 | 665 |
env = saved_env; |
663 | 666 |
} |
Also available in: Unified diff