--- trunk/src/cpus/cpu_dyntrans.c 2007/10/08 16:20:40 30 +++ trunk/src/cpus/cpu_dyntrans.c 2007/10/08 16:20:58 32 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: cpu_dyntrans.c,v 1.120 2006/08/12 11:43:12 debug Exp $ + * $Id: cpu_dyntrans.c,v 1.132 2006/10/27 13:12:20 debug Exp $ * * Common dyntrans routines. Included from cpu_*.c. */ @@ -45,6 +45,12 @@ int low_pc = ((size_t)cpu->cd.DYNTRANS_ARCH.next_ic - (size_t) cpu->cd.DYNTRANS_ARCH.cur_ic_page) / sizeof(struct DYNTRANS_IC); + if (cpu->machine->statistics_file == NULL) { + fatal("statistics gathering with no filename set is" + " meaningless\n"); + return; + } + buf[0] = '\0'; while ((ch = cpu->machine->statistics_fields[i]) != '\0') { @@ -230,6 +236,12 @@ if (cpu->cd.ppc.irq_asserted && cpu->cd.ppc.msr & PPC_MSR_EE) ppc_exception(cpu, PPC_EXCEPTION_EI); #endif +#ifdef DYNTRANS_SH + if (cpu->cd.sh.int_to_assert > 0 && !(cpu->cd.sh.sr & SH_SR_BL) + && ((cpu->cd.sh.sr & SH_SR_IMASK) >> SH_SR_IMASK_SHIFT) + < cpu->cd.sh.int_level) + sh_exception(cpu, 0, cpu->cd.sh.int_to_assert, 0); +#endif cached_pc = cpu->pc; @@ -249,25 +261,24 @@ cpu_register_dump(cpu->machine, cpu, 1, 0x1); } if (cpu->machine->instruction_trace) { + /* TODO/Note: This must be large enough to hold + any instruction for any ISA: */ + unsigned char instr[1 << + DYNTRANS_INSTR_ALIGNMENT_SHIFT]; #ifdef DYNTRANS_X86 - unsigned char instr[17]; cpu->cd.x86.cursegment = X86_S_CS; cpu->cd.x86.seg_override = 0; -#else -#ifdef DYNTRANS_M68K - unsigned char instr[16]; /* TODO: 16? */ -#else - unsigned char instr[4]; /* General case... */ -#endif #endif - if (!cpu->memory_rw(cpu, cpu->mem, cached_pc, &instr[0], sizeof(instr), MEM_READ, CACHE_INSTRUCTION)) { fatal("XXX_run_instr(): could not read " "the instruction\n"); } else { - cpu_disassemble_instr(cpu->machine, cpu, - instr, 1, 0); +#ifdef DYNTRANS_DELAYSLOT + int len = +#endif + cpu_disassemble_instr( + cpu->machine, cpu, instr, 1, 0); #ifdef DYNTRANS_DELAYSLOT /* Show the instruction in the delay slot, if any: */ @@ -278,15 +289,15 @@ instr)) { int saved_delayslot = cpu->delay_slot; cpu->memory_rw(cpu, cpu->mem, cached_pc - + sizeof(instr), &instr[0], + + len, &instr[0], sizeof(instr), MEM_READ, CACHE_INSTRUCTION); cpu->delay_slot = DELAYED; - cpu->pc += sizeof(instr); + cpu->pc += len; cpu_disassemble_instr(cpu->machine, cpu, instr, 1, 0); cpu->delay_slot = saved_delayslot; - cpu->pc -= sizeof(instr); + cpu->pc -= len; } #endif } @@ -394,8 +405,20 @@ (int32_t) (old + n_instrs); diff2 = cpu->cd.mips.coproc[0]->reg[COP0_COMPARE] - cpu->cd.mips.coproc[0]->reg[COP0_COUNT]; - if (cpu->cd.mips.compare_register_set && diff1>0 && diff2<=0) - cpu_interrupt(cpu, 7); + + if (cpu->cd.mips.compare_register_set) { +#if 1 +/* Not yet. TODO */ + if (cpu->machine->emulated_hz > 0) { + if (cpu->cd.mips.compare_interrupts_pending > 0) + cpu_interrupt(cpu, 7); + } else +#endif + { + if (diff1 > 0 && diff2 <= 0) + cpu_interrupt(cpu, 7); + } + } } #endif #ifdef DYNTRANS_PPC @@ -438,7 +461,7 @@ 6 #else #ifdef DYNTRANS_SH - 8 + 8 /* Both for 32-bit and 64-bit SuperH */ #else 4 /* Default value for most archs */ #endif @@ -479,6 +502,9 @@ they go downwards, ie. 22,23 and so on */ r[24 #endif +#ifdef DYNTRANS_AVR32 + r[0 /* TODO */ +#endif #ifdef DYNTRANS_HPPA r[0 /* TODO */ #endif @@ -497,11 +523,15 @@ #ifdef DYNTRANS_PPC gpr[3 #endif +#ifdef DYNTRANS_RCA180X + r[0 /* TODO */ +#endif #ifdef DYNTRANS_SH - r[2 + r[4 /* NetBSD seems to use 4? But 2 seems + to be used by other code? TODO */ #endif #ifdef DYNTRANS_SPARC - r[24 + r[8 /* o0..o5 */ #endif + x]; #endif @@ -1341,7 +1371,7 @@ void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page) { - int found, r, lowest_index, useraccess = 0; + int found, r, useraccess = 0; #ifdef MODE32 uint32_t index; @@ -1372,7 +1402,6 @@ } /* Scan the current TLB entries: */ - lowest_index = 0; #ifdef MODE32 /* @@ -1404,13 +1433,10 @@ #endif if (found < 0) { + /* Create the new TLB entry, overwriting a "random" entry: */ static unsigned int x = 0; - lowest_index = (x++) % DYNTRANS_MAX_VPH_TLB_ENTRIES; - } + r = (x++) % DYNTRANS_MAX_VPH_TLB_ENTRIES; - if (found < 0) { - /* Create the new TLB entry, overwriting the oldest one: */ - r = lowest_index; if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) { /* This one has to be invalidated first: */ DYNTRANS_INVALIDATE_TLB_ENTRY(cpu,