--- trunk/src/bintrans.c 2007/10/08 16:17:48 2 +++ trunk/src/bintrans.c 2007/10/08 16:18:00 4 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: bintrans.c,v 1.160 2005/04/06 21:16:45 debug Exp $ + * $Id: bintrans.c,v 1.165 2005/04/27 16:37:34 debug Exp $ * * Dynamic binary translation. * @@ -123,6 +123,7 @@ int bintrans_pc_is_in_cache(struct cpu *cpu, uint64_t pc) { return 0; } void bintrans_invalidate(struct cpu *cpu, uint64_t paddr) { } int bintrans_attempt_translate(struct cpu *cpu, uint64_t paddr) { return 0; } +void bintrans_restart(struct cpu *cpu) { } void bintrans_init_cpu(struct cpu *cpu) { } void bintrans_init(struct machine *machine, struct memory *mem) { @@ -278,6 +279,26 @@ /* + * bintrans_restart(): + * + * Starts over by throwing away the bintrans cache contents. + */ +void bintrans_restart(struct cpu *cpu) +{ + int i, n = 1 << BINTRANS_CACHE_N_INDEX_BITS; + + for (i=0; imem->translation_page_entry_array[i] = NULL; + + cpu->mem->translation_code_chunk_space_head = 0; + cpu->mem->n_quick_jumps = 0; + + /* debug("bintrans: Starting over!\n"); */ + clear_all_chunks_from_all_tables(cpu); +} + + +/* * enter_chunks_into_tables(): */ static void enter_chunks_into_tables(struct cpu *cpu, uint64_t vaddr, @@ -337,24 +358,24 @@ (paddr & 3) != 0) return cpu->cd.mips.bintrans_instructions_executed; - cpu->mem->bintrans_32bit_only = (cpu->cd.mips.cpu_type.isa_level <= 2 - || cpu->cd.mips.cpu_type.isa_level == 32); byte_order_cached_bigendian = (cpu->byte_order == EMUL_BIG_ENDIAN); /* Is this a part of something that is already translated? */ paddr_page = paddr & ~0xfff; - offset_within_page = (paddr & 0xfff) / 4; + offset_within_page = (paddr & 0xfff) >> 2; entry_index = PADDR_TO_INDEX(paddr); tep = cpu->mem->translation_page_entry_array[entry_index]; while (tep != NULL) { if (tep->paddr == paddr_page) { - int mask = 1 << (offset_within_page & 7); + int mask; if (tep->chunk[offset_within_page] != 0) { f = (size_t)tep->chunk[offset_within_page] + cpu->mem->translation_code_chunk_space; goto run_it; /* see further down */ } + + mask = 1 << (offset_within_page & 7); if (tep->flags[offset_within_page >> 3] & mask) return cpu->cd.mips. bintrans_instructions_executed; @@ -380,14 +401,8 @@ */ if (cpu->mem->translation_code_chunk_space_head >= cpu->machine->bintrans_size) { - int i, n = 1 << BINTRANS_CACHE_N_INDEX_BITS; - for (i=0; imem->translation_page_entry_array[i] = NULL; - cpu->mem->translation_code_chunk_space_head = 0; - cpu->mem->n_quick_jumps = 0; + bintrans_restart(cpu); tep = NULL; - debug("bintrans: Starting over!\n"); - clear_all_chunks_from_all_tables(cpu); } @@ -434,6 +449,7 @@ * Try to translate a chunk of code: */ p = paddr & 0xfff; + prev_p = p >> 2; try_to_translate = 1; n_translated = 0; res = 0; @@ -445,7 +461,6 @@ while (try_to_translate) { ca_justdid = ca; - prev_p = p/4; translated = 0; /* Read an instruction word from host memory: */ @@ -621,17 +636,18 @@ case HI6_XORI: case HI6_DADDI: case HI6_DADDIU: - rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7); - rt = instr[2] & 31; - imm = (instr[1] << 8) + instr[0]; - translated = try_to_translate = bintrans_write_instruction__addiu_etc(&ca, rt, rs, imm, hi6); + translated = try_to_translate = + bintrans_write_instruction__addiu_etc(&ca, + instr[2] & 31, + ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7), + (instr[1] << 8) + instr[0], hi6); n_translated += translated; break; case HI6_LUI: - rt = instr[2] & 31; - imm = (instr[1] << 8) + instr[0]; - translated = try_to_translate = bintrans_write_instruction__lui(&ca, rt, imm); + translated = try_to_translate = + bintrans_write_instruction__lui(&ca, + instr[2] & 31, (instr[1] << 8) + instr[0]); n_translated += translated; break; @@ -664,7 +680,8 @@ translated = try_to_translate = bintrans_write_instruction__mfc_mtc(cpu->mem, &ca, 0, 1, rt, rd, 1); n_translated += translated; } - } + } else + try_to_translate = 0; break; case 0x42: if (instr[2] == 0x00 && instr[1] == 0x00 && instr[0] == 0x10) { @@ -697,7 +714,8 @@ /* standby and suspend on VR41xx etc ==> NOP */ translated = try_to_translate = bintrans_write_instruction__addu_etc(&ca, 0, 0, 0, 0, SPECIAL_SLL); n_translated += translated; - } + } else + try_to_translate = 0; break; default: try_to_translate = 0; @@ -773,9 +791,10 @@ cpu->mem, &ca, potential_chunk_p, &tep->chunk[0], 0, delayed_branch_new_p & 0xfff, forward); - +#if 0 if (stop_after_delayed_branch) try_to_translate = 0; +#endif } } @@ -796,33 +815,35 @@ tep->chunk[prev_p]); } - /* Glue together with previously translated code, if any: */ - if (translated && try_to_translate && - prev_p < 1023 && tep->chunk[prev_p+1] != 0 - && !delayed_branch) { - bintrans_write_instruction__delayedbranch(cpu->mem, - &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1); - try_to_translate = 0; - } + if (translated && try_to_translate && prev_p < 1023) { + int mask = 1 << ((prev_p+1) & 7); - if (translated && try_to_translate && n_translated > 80 - && prev_p < 1023 && !delayed_branch) { - bintrans_write_instruction__delayedbranch(cpu->mem, - &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1); - try_to_translate = 0; - } + if (tep->flags[(prev_p+1) >> 3] & mask + && !delayed_branch) { + bintrans_write_chunkreturn_fail(&ca); + /* try_to_translate = 0; */ + break; + } -{ - int mask = 1 << ((prev_p+1) & 7); + /* Glue together with previously translated code, + if any: */ + if (tep->chunk[prev_p+1] != 0 && !delayed_branch) { + bintrans_write_instruction__delayedbranch(cpu->mem, + &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1); + /* try_to_translate = 0; */ + break; + } - if (translated && try_to_translate && - tep->flags[(prev_p+1) >> 3] & mask - && prev_p < 1023 && !delayed_branch) { - bintrans_write_chunkreturn_fail(&ca); + if (n_translated > 80 && !delayed_branch) { + bintrans_write_instruction__delayedbranch(cpu->mem, + &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1); + /* try_to_translate = 0; */ + break; + } } -} p += sizeof(instr); + prev_p ++; /* If we have reached a different (MIPS) page, then stop translating. */ if (p == 0x1000) @@ -921,17 +942,18 @@ if (ok) { paddr_page = paddr & ~0xfff; - offset_within_page = (paddr & 0xfff) / 4; + offset_within_page = (paddr & 0xfff) >> 2; entry_index = PADDR_TO_INDEX(paddr); tep = cpu->mem->translation_page_entry_array[entry_index]; while (tep != NULL) { if (tep->paddr == paddr_page) { - int mask = 1 << (offset_within_page & 7); + int mask; if (tep->chunk[offset_within_page] != 0) { f = (size_t)tep->chunk[offset_within_page] + cpu->mem->translation_code_chunk_space; goto run_it; } + mask = 1 << (offset_within_page & 7); if (tep->flags[offset_within_page >> 3] & mask) return cpu->cd.mips.bintrans_instructions_executed; break; @@ -1071,6 +1093,9 @@ } cpu->cd.mips.vaddr_to_hostaddr_table0 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel; + + cpu->mem->bintrans_32bit_only = (cpu->cd.mips.cpu_type.isa_level <= 2 + || cpu->cd.mips.cpu_type.isa_level == 32); }