--- trunk/src/cpus/cpu_dyntrans.c 2007/10/08 16:20:26 28 +++ trunk/src/cpus/cpu_dyntrans.c 2007/10/08 16:20:40 30 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: cpu_dyntrans.c,v 1.113 2006/07/21 20:09:15 debug Exp $ + * $Id: cpu_dyntrans.c,v 1.120 2006/08/12 11:43:12 debug Exp $ * * Common dyntrans routines. Included from cpu_*.c. */ @@ -223,7 +223,8 @@ #endif #ifdef DYNTRANS_PPC if (cpu->cd.ppc.dec_intr_pending && cpu->cd.ppc.msr & PPC_MSR_EE) { - ppc_exception(cpu, PPC_EXCEPTION_DEC); + if (!(cpu->cd.ppc.cpu_type.flags & PPC_NO_DEC)) + ppc_exception(cpu, PPC_EXCEPTION_DEC); cpu->cd.ppc.dec_intr_pending = 0; } if (cpu->cd.ppc.irq_asserted && cpu->cd.ppc.msr & PPC_MSR_EE) @@ -233,7 +234,6 @@ cached_pc = cpu->pc; cpu->n_translated_instrs = 0; - cpu->running_translated = 1; cpu->cd.DYNTRANS_ARCH.cur_physpage = (void *) cpu->cd.DYNTRANS_ARCH.cur_ic_page; @@ -292,34 +292,6 @@ } } - /* When single-stepping, multiple instruction calls cannot - be combined into one. This clears all translations: */ - if (cpu->cd.DYNTRANS_ARCH.cur_physpage->flags & COMBINATIONS) { - int i; - for (i=0; icd.DYNTRANS_ARCH.cur_physpage->ics[i].f = -#ifdef DYNTRANS_DUALMODE_32 - cpu->is_32bit? - instr32(to_be_translated) : -#endif - instr(to_be_translated); -#ifdef DYNTRANS_VARIABLE_INSTRUCTION_LENGTH - cpu->cd.DYNTRANS_ARCH.cur_physpage->ics[i]. - arg[0] = 0; -#endif - } - - fatal("[ Note: The translation of physical page 0x%" - PRIx64" contained combinations of instructions; " - "these are now flushed because we are single-" - "stepping. ]\n", (long long)cpu->cd.DYNTRANS_ARCH. - cur_physpage->physaddr); - - cpu->cd.DYNTRANS_ARCH.cur_physpage->flags &= - ~COMBINATIONS; - cpu->cd.DYNTRANS_ARCH.cur_physpage->translations = 0; - } - if (cpu->machine->statistics_enabled) S; @@ -344,8 +316,7 @@ cpu->machine->tick_func[1](cpu, cpu->machine->tick_extra[1]); /* printf("B\n"); */ - if (!cpu->running_translated || - n_instrs + cpu->n_translated_instrs >= + if (n_instrs + cpu->n_translated_instrs >= N_SAFE_DYNTRANS_LIMIT) break; } @@ -362,14 +333,13 @@ n_instrs += 24; - if (!cpu->running_translated || - n_instrs + cpu->n_translated_instrs >= + if (n_instrs + cpu->n_translated_instrs >= N_SAFE_DYNTRANS_LIMIT) break; } } else { /* Execute multiple instructions: */ - n_instrs = 0; + int n = 0; for (;;) { struct DYNTRANS_IC *ic; @@ -381,13 +351,13 @@ I; I; I; I; I; I; I; I; I; I; - n_instrs += 60; + n += 60; - if (!cpu->running_translated || - n_instrs + cpu->n_translated_instrs >= + if (n + cpu->n_translated_instrs >= N_SAFE_DYNTRANS_LIMIT) break; } + n_instrs = n; } n_instrs += cpu->n_translated_instrs; @@ -650,8 +620,14 @@ if (!ok) { uint64_t paddr; if (cpu->translate_v2p != NULL) { + uint64_t vaddr = +#if defined(MODE32) && defined(DYNTRANS_MIPS) + /* 32-bit MIPS is _sign_ extend, not zero. */ + (int32_t) +#endif + cached_pc; ok = cpu->translate_v2p( - cpu, cached_pc, &paddr, FLAG_INSTR); + cpu, vaddr, &paddr, FLAG_INSTR); } else { paddr = cached_pc; ok = 1; @@ -902,7 +878,6 @@ } ppp->next_ofs = 0; - ppp->flags = 0; ppp->translations = 0; /* ppp->physaddr is filled in by the page allocator */ @@ -1312,7 +1287,6 @@ x >>= 1; } - ppp->flags &= ~COMBINATIONS; ppp->translations = 0; } #endif @@ -1367,9 +1341,6 @@ void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page) { -#ifndef MODE32 - int64_t lowest, highest = -1; -#endif int found, r, lowest_index, useraccess = 0; #ifdef MODE32 @@ -1414,30 +1385,28 @@ */ found = (int)cpu->cd.DYNTRANS_ARCH.vaddr_to_tlbindex[ DYNTRANS_ADDR_TO_PAGENR(vaddr_page)] - 1; +#else + x1 = (vaddr_page >> (64-DYNTRANS_L1N)) & mask1; + x2 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2; + x3 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N)) + & mask3; + + l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1]; + if (l2 == cpu->cd.DYNTRANS_ARCH.l2_64_dummy) + found = -1; + else { + l3 = l2->l3[x2]; + if (l3 == cpu->cd.DYNTRANS_ARCH.l3_64_dummy) + found = -1; + else + found = (int)l3->vaddr_to_tlbindex[x3] - 1; + } +#endif + if (found < 0) { static unsigned int x = 0; lowest_index = (x++) % DYNTRANS_MAX_VPH_TLB_ENTRIES; } -#else - lowest = cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[0].timestamp; - found = -1; - for (r=0; rcd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp < lowest) { - lowest = cpu->cd.DYNTRANS_ARCH. - vph_tlb_entry[r].timestamp; - lowest_index = r; - } - if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp > highest) - highest = cpu->cd.DYNTRANS_ARCH. - vph_tlb_entry[r].timestamp; - if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid && - cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page == - vaddr_page) { - found = r; - break; - } - } -#endif if (found < 0) { /* Create the new TLB entry, overwriting the oldest one: */ @@ -1455,9 +1424,6 @@ cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page = vaddr_page; cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = writeflag & MEM_WRITE; -#ifndef MODE32 - cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1; -#endif /* Add the new translation to the table: */ #ifdef MODE32 @@ -1474,11 +1440,6 @@ |= 1 << (index & 31); #endif #else /* !MODE32 */ - x1 = (vaddr_page >> (64-DYNTRANS_L1N)) & mask1; - x2 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2; - x3 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N)) - & mask3; - l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1]; if (l2 == cpu->cd.DYNTRANS_ARCH.l2_64_dummy) { if (cpu->cd.DYNTRANS_ARCH.next_free_l2 != NULL) { @@ -1563,9 +1524,6 @@ * Writeflag = MEM_DOWNGRADE: Downgrade to readonly. */ r = found; -#ifndef MODE32 - cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1; -#endif if (writeflag & MEM_WRITE) cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 1; if (writeflag & MEM_DOWNGRADE) @@ -1714,11 +1672,10 @@ #ifdef DYNTRANS_DELAYSLOT && !in_crosspage_delayslot #endif - ) { - if (cpu->cd.DYNTRANS_ARCH.combination_check != NULL && - cpu->machine->allow_instruction_combinations) - cpu->cd.DYNTRANS_ARCH.combination_check(cpu, ic, - addr & (DYNTRANS_PAGESIZE - 1)); + && cpu->cd.DYNTRANS_ARCH.combination_check != NULL + && cpu->machine->allow_instruction_combinations) { + cpu->cd.DYNTRANS_ARCH.combination_check(cpu, ic, + addr & (DYNTRANS_PAGESIZE - 1)); } cpu->cd.DYNTRANS_ARCH.combination_check = NULL; @@ -1798,14 +1755,17 @@ } cpu->running = 0; - cpu->dead = 1; + + /* Note: Single-stepping can jump here. */ stop_running_translated: + debugger_n_steps_left_before_interaction = 0; - cpu->running_translated = 0; + ic = cpu->cd.DYNTRANS_ARCH.next_ic = ¬hing_call; cpu->cd.DYNTRANS_ARCH.next_ic ++; /* Execute the "nothing" instruction: */ ic->f(cpu, ic); + #endif /* DYNTRANS_TO_BE_TRANSLATED_TAIL */