--- trunk/src/bintrans.c 2007/10/08 16:18:27 10 +++ trunk/src/bintrans.c 2007/10/08 16:18:38 12 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: bintrans.c,v 1.169 2005/06/22 10:12:25 debug Exp $ + * $Id: bintrans.c,v 1.177 2005/08/14 15:47:36 debug Exp $ * * Dynamic binary translation. * @@ -81,9 +81,6 @@ * * o) Load/stores: TODO: Comment. * - * Testing: Running regression tests with and without the binary translator - * enabled should obviously result in the exact same results, or something is - * wrong. * * The general idea is something like this: * @@ -142,10 +139,12 @@ static void bintrans_write_pc_inc(unsigned char **addrp); static void bintrans_write_quickjump(struct memory *mem, unsigned char *quickjump_code, uint32_t chunkoffset); -static int bintrans_write_instruction__addiu_etc(unsigned char **addrp, int rt, - int rs, int imm, int instruction_type); -static int bintrans_write_instruction__addu_etc(unsigned char **addrp, int rd, - int rs, int rt, int sa, int instruction_type); +static int bintrans_write_instruction__addiu_etc(struct memory *mem, + unsigned char **addrp, int rt, int rs, int imm, + int instruction_type); +static int bintrans_write_instruction__addu_etc(struct memory *mem, + unsigned char **addrp, int rd, int rs, int rt, int sa, + int instruction_type); static int bintrans_write_instruction__branch(unsigned char **addrp, int instruction_type, int regimm_type, int rt, int rs, int imm); static int bintrans_write_instruction__jr(unsigned char **addrp, int rs, @@ -157,7 +156,7 @@ int only_care_about_chunk_p, int p, int forward); static int bintrans_write_instruction__loadstore(struct memory *mem, unsigned char **addrp, int rt, int imm, int rs, int instruction_type, - int bigendian); + int bigendian, int do_alignment_check); static int bintrans_write_instruction__lui(unsigned char **addrp, int rt, int imm); static int bintrans_write_instruction__mfmthilo(unsigned char **addrp, int rd, @@ -202,17 +201,7 @@ #define BACKEND_NAME "i386" #include "bintrans_i386.c" #else -#ifdef MIPS -#define BACKEND_NAME "MIPS" -#include "bintrans_mips.c" -#else -#ifdef SPARCV9 -#define BACKEND_NAME "UltraSPARC" -#include "bintrans_sparcv9.c" -#else #error Unsupported host architecture for bintrans. -#endif /* SPARCV9 */ -#endif /* MIPS */ #endif /* I386 */ #endif /* ALPHA */ @@ -287,13 +276,16 @@ { int i, n = 1 << BINTRANS_CACHE_N_INDEX_BITS; + if (cpu->machine->arch != ARCH_MIPS) + return; + 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"); */ + debug("[ bintrans: Starting over! ]\n"); clear_all_chunks_from_all_tables(cpu); } @@ -348,7 +340,7 @@ int rs,rt,rd,sa,imm; uint32_t *potential_chunk_p; /* for branches */ int byte_order_cached_bigendian; - int delayed_branch, stop_after_delayed_branch; + int delayed_branch, stop_after_delayed_branch, return_code_written; uint64_t delayed_branch_new_p; int prev_p; @@ -420,8 +412,7 @@ /* ... and align again: */ cpu->mem->translation_code_chunk_space_head = - ((cpu->mem->translation_code_chunk_space_head - 1) | 63) - + 1; + ((cpu->mem->translation_code_chunk_space_head - 1) | 31)+1; /* Add the entry to the array: */ memset(tep, 0, sizeof(struct translation_page_entry)); @@ -453,6 +444,7 @@ try_to_translate = 1; n_translated = 0; res = 0; + return_code_written = 0; delayed_branch = 0; stop_after_delayed_branch = 0; delayed_branch_new_p = 0; @@ -503,6 +495,7 @@ bintrans_write_chunkreturn_fail(&ca); tep->flags[prev_p >> 3] |= mask; try_to_translate = 0; + return_code_written = 1; } else { translated = bintrans_write_instruction__tlb_rfe_etc(&ca, special6 == SPECIAL_BREAK? CALL_BREAK : CALL_SYSCALL); @@ -544,7 +537,7 @@ rd = rt = rs = sa = 0; special6 = SPECIAL_SLL; } - translated = try_to_translate = bintrans_write_instruction__addu_etc(&ca, rd, rs, rt, sa, special6); + translated = try_to_translate = bintrans_write_instruction__addu_etc(cpu->mem, &ca, rd, rs, rt, sa, special6); n_translated += translated; break; case SPECIAL_MFHI: @@ -566,6 +559,7 @@ tep->flags[prev_p >> 3] |= mask; } try_to_translate = 0; + return_code_written = 1; } break; @@ -584,7 +578,6 @@ delayed_branch_new_p = p + 4 + 4*imm; break; default: - try_to_translate = 0; /* Untranslatable: */ /* TODO: this code should only be in one place */ bintrans_write_chunkreturn_fail(&ca); @@ -593,6 +586,7 @@ tep->flags[prev_p >> 3] |= mask; } try_to_translate = 0; + return_code_written = 1; } break; @@ -637,8 +631,8 @@ case HI6_DADDI: case HI6_DADDIU: translated = try_to_translate = - bintrans_write_instruction__addiu_etc(&ca, - instr[2] & 31, + bintrans_write_instruction__addiu_etc(cpu->mem, + &ca, instr[2] & 31, ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7), (instr[1] << 8) + instr[0], hi6); n_translated += translated; @@ -680,8 +674,17 @@ translated = try_to_translate = bintrans_write_instruction__mfc_mtc(cpu->mem, &ca, 0, 1, rt, rd, 1); n_translated += translated; } - } else + } else { + /* Untranslatable: */ + /* TODO: this code should only be in one place */ + bintrans_write_chunkreturn_fail(&ca); + { + int mask = 1 << (prev_p & 7); + tep->flags[prev_p >> 3] |= mask; + } try_to_translate = 0; + return_code_written = 1; + } break; case 0x42: if (instr[2] == 0x00 && instr[1] == 0x00 && instr[0] == 0x10) { @@ -712,16 +715,32 @@ n_translated += translated; } else if (instr[2] == 0 && instr[1] == 0 && (instr[0] == 0x21 || instr[0] == 0x22)) { /* standby and suspend on VR41xx etc ==> NOP */ - translated = try_to_translate = bintrans_write_instruction__addu_etc(&ca, 0, 0, 0, 0, SPECIAL_SLL); + translated = try_to_translate = bintrans_write_instruction__addu_etc(cpu->mem, &ca, 0, 0, 0, 0, SPECIAL_SLL); n_translated += translated; - } else + } else { + /* Untranslatable: */ + /* TODO: this code should only be in one place */ + bintrans_write_chunkreturn_fail(&ca); + { + int mask = 1 << (prev_p & 7); + tep->flags[prev_p >> 3] |= mask; + } try_to_translate = 0; + return_code_written = 1; + } break; default: + /* Untranslatable: */ + /* TODO: this code should only be in one place */ + bintrans_write_chunkreturn_fail(&ca); + { + int mask = 1 << (prev_p & 7); + tep->flags[prev_p >> 3] |= mask; + } try_to_translate = 0; + return_code_written = 1; } break; - #if 0 case HI6_LQ_MDMX: #endif @@ -748,12 +767,14 @@ imm = (instr[1] << 8) + instr[0]; if (imm >= 32768) imm -= 65536; - translated = try_to_translate = bintrans_write_instruction__loadstore(cpu->mem, &ca, rt, imm, rs, hi6, byte_order_cached_bigendian); + translated = try_to_translate = bintrans_write_instruction__loadstore(cpu->mem, &ca, rt, imm, rs, hi6, + byte_order_cached_bigendian, + cpu->machine->dyntrans_alignment_check); n_translated += translated; break; case HI6_CACHE: - translated = try_to_translate = bintrans_write_instruction__addu_etc(&ca, 0, 0, 0, 0, SPECIAL_SLL); + translated = try_to_translate = bintrans_write_instruction__addu_etc(cpu->mem, &ca, 0, 0, 0, 0, SPECIAL_SLL); n_translated += translated; break; @@ -766,6 +787,7 @@ tep->flags[prev_p >> 3] |= mask; } try_to_translate = 0; + return_code_written = 1; } if (translated && delayed_branch) { @@ -791,10 +813,9 @@ 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 } } @@ -821,7 +842,8 @@ if (tep->flags[(prev_p+1) >> 3] & mask && !delayed_branch) { bintrans_write_chunkreturn_fail(&ca); - /* try_to_translate = 0; */ + try_to_translate = 0; + return_code_written = 1; break; } @@ -830,14 +852,17 @@ 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; + return_code_written = 1; /* try_to_translate = 0; */ break; } - if (n_translated > 80 && !delayed_branch) { + if (n_translated > 120 && !delayed_branch) { bintrans_write_instruction__delayedbranch(cpu->mem, &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1); - /* try_to_translate = 0; */ + try_to_translate = 0; + return_code_written = 1; break; } } @@ -864,7 +889,8 @@ cpu->mem->translation_code_chunk_space_head; /* Add return code: */ - bintrans_write_chunkreturn(&ca); + if (!return_code_written) + bintrans_write_chunkreturn(&ca); /* chunk_len = nr of bytes occupied by the new code chunk */ chunk_len = (size_t)ca - (size_t)ca2; @@ -876,7 +902,7 @@ /* Align the code chunk space: */ cpu->mem->translation_code_chunk_space_head = - ((cpu->mem->translation_code_chunk_space_head - 1) | 63) + 1; + ((cpu->mem->translation_code_chunk_space_head - 1) | 31) + 1; /* RUN the code chunk: */ @@ -1067,6 +1093,23 @@ } cpu->cd.mips.vaddr_to_hostaddr_r2k3k_dcachetable->refcount = 1024; + /* 1M entry cache stuff for R2K/3K: */ + if (cpu->cd.mips.cpu_type.isa_level == 1) { + cpu->cd.mips.huge_r2k3k_cache_table = + zeroed_alloc(1048576 * sizeof(unsigned char *)); +#if 1 + for (i=0; i<1048576; i++) { + unsigned char *ptr = NULL; + if (i < (0xa0000000ULL >> 12) || + i >= (0xc0000000ULL >> 12)) + ptr = cpu->cd.mips. + vaddr_to_hostaddr_r2k3k_dcachetable + ->haddr_entry[(i & 1023) * 2]; + cpu->cd.mips.huge_r2k3k_cache_table[i] = ptr; + } +#endif + } + /* Instruction cache: */ offset = 0; cpu->cd.mips.vaddr_to_hostaddr_r2k3k_icachetable =