diff --git a/libpcsxcore/new_dynarec/assem_arm64.c b/libpcsxcore/new_dynarec/assem_arm64.c index 259c8e88..5d6a7829 100644 --- a/libpcsxcore/new_dynarec/assem_arm64.c +++ b/libpcsxcore/new_dynarec/assem_arm64.c @@ -2038,6 +2038,7 @@ static void do_jump_vaddr(u_int rs) { if (rs != 0) emit_mov(rs, 0); + emit_readptr(&hash_table_ptr, 1); emit_far_call(ndrc_get_addr_ht); emit_jmpreg(0); } diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index 0b8d9e2b..4b2b3cf0 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -356,11 +356,14 @@ static void ari64_execute_threaded_once(struct psxRegisters *regs, enum blockExecCaller block_caller) { void *drc_local = (char *)regs - LO_psxRegs; + struct ht_entry *hash_table = + *(void **)((char *)drc_local + LO_hash_table_ptr); void *target; if (likely(!ndrc_g.thread.busy)) { ndrc_g.thread.addr = 0; - target = ndrc_get_addr_ht_param(regs->pc, ndrc_cm_no_compile); + target = ndrc_get_addr_ht_param(hash_table, regs->pc, + ndrc_cm_no_compile); if (target) { clear_local_cache(); new_dyna_start_at(drc_local, target); @@ -428,6 +431,8 @@ static int ari64_thread_check_range(unsigned int start, unsigned int end) static void ari64_compile_thread(void *unused) { + struct ht_entry *hash_table = + *(void **)((char *)dynarec_local + LO_hash_table_ptr); void *target; u32 addr; @@ -440,7 +445,8 @@ static void ari64_compile_thread(void *unused) if (!ndrc_g.thread.busy || !addr || ndrc_g.thread.exit) continue; - target = ndrc_get_addr_ht_param(addr, ndrc_cm_compile_in_thread); + target = ndrc_get_addr_ht_param(hash_table, addr, + ndrc_cm_compile_in_thread); //printf("c %08x -> %p\n", addr, target); ndrc_g.thread.busy = 0; } @@ -520,7 +526,6 @@ static int ari64_thread_check_range(unsigned int start, unsigned int end) { retu static int ari64_init() { - static u32 scratch_buf[8*8*2] __attribute__((aligned(64))); size_t i; new_dynarec_init(); @@ -548,7 +553,6 @@ static int ari64_init() #endif psxH_ptr = psxH; zeromem_ptr = zero_mem; - scratch_buf_ptr = scratch_buf; ari64_thread_init(); @@ -576,11 +580,6 @@ R3000Acpu psxRec = { #else // if DRC_DISABLE struct ndrc_globals ndrc_g; // dummy -void *psxH_ptr; -void *zeromem_ptr; -u32 zero_mem[0x1000/4]; -void *mem_rtab; -void *scratch_buf_ptr; void new_dynarec_init() {} void new_dyna_start(void *context) {} void new_dynarec_cleanup() {} diff --git a/libpcsxcore/new_dynarec/linkage_arm.S b/libpcsxcore/new_dynarec/linkage_arm.S index 1d8880ae..d660ed59 100644 --- a/libpcsxcore/new_dynarec/linkage_arm.S +++ b/libpcsxcore/new_dynarec/linkage_arm.S @@ -79,7 +79,7 @@ DRC_VAR(mem_wtab, 4) DRC_VAR(psxH_ptr, 4) DRC_VAR(zeromem_ptr, 4) DRC_VAR(invc_ptr, 4) -DRC_VAR(scratch_buf_ptr, 4) +DRC_VAR(hash_table_ptr, 4) DRC_VAR(ram_offset, 4) DRC_VAR(mini_ht, 256) @@ -150,7 +150,9 @@ FUNCTION(dyna_linker): mov r5, r1 lsl r6, r6, #8 /* must not compile - that might expire the caller block */ - mov r1, #0 /* ndrc_compile_mode */ + ldr r0, [fp, #LO_hash_table_ptr] + mov r1, r4 + mov r2, #0 /* ndrc_compile_mode=ndrc_cm_no_compile */ bl ndrc_get_addr_ht_param movs r8, r0 @@ -174,6 +176,7 @@ FUNCTION(dyna_linker): #else /* XXX: should be able to do better than this... */ #endif + ldr r1, [fp, #LO_hash_table_ptr] bl ndrc_get_addr_ht mov pc, r0 .size dyna_linker, .-dyna_linker @@ -223,6 +226,7 @@ FUNCTION(jump_vaddr_r7): add r0, r7, #0 .size jump_vaddr_r7, .-jump_vaddr_r7 FUNCTION(jump_vaddr_r0): + ldr r1, [fp, #LO_hash_table_ptr] bl ndrc_get_addr_ht mov pc, r0 .size jump_vaddr_r0, .-jump_vaddr_r0 @@ -248,6 +252,7 @@ FUNCTION(cc_interrupt): ldmfdne sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc} cmp r0, r9 moveq pc, lr + ldr r1, [fp, #LO_hash_table_ptr] bl ndrc_get_addr_ht mov pc, r0 .size cc_interrupt, .-cc_interrupt @@ -304,6 +309,7 @@ FUNCTION(jump_to_new_pc): str r1, [fp, #LO_last_count] sub r10, r10, r1 bne new_dyna_leave + ldr r1, [fp, #LO_hash_table_ptr] bl ndrc_get_addr_ht mov pc, r0 .size jump_to_new_pc, .-jump_to_new_pc @@ -408,6 +414,7 @@ FUNCTION(new_dyna_start): stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} mov fp, r0 /* dynarec_local */ ldr r0, [fp, #LO_pcaddr] + ldr r1, [fp, #LO_hash_table_ptr] bl ndrc_get_addr_ht new_dyna_start_at_e: ldr r1, [fp, #LO_next_interupt] diff --git a/libpcsxcore/new_dynarec/linkage_arm64.S b/libpcsxcore/new_dynarec/linkage_arm64.S index 155e0e2f..45eca556 100644 --- a/libpcsxcore/new_dynarec/linkage_arm64.S +++ b/libpcsxcore/new_dynarec/linkage_arm64.S @@ -81,7 +81,7 @@ DRC_VAR(mem_wtab, 8) DRC_VAR(psxH_ptr, 8) DRC_VAR(invc_ptr, 8) DRC_VAR(zeromem_ptr, 8) -DRC_VAR(scratch_buf_ptr, 8) +DRC_VAR(hash_table_ptr, 8) DRC_VAR(ram_offset, 8) DRC_VAR(mini_ht, 256) @@ -92,6 +92,7 @@ DRC_VAR(mini_ht, 256) FUNCTION(dyna_linker): /* r0 = virtual target address */ /* r1 = instruction to patch */ + ldr x1, [rFP, #LO_hash_table_ptr] bl ndrc_get_addr_ht br x0 ESIZE(dyna_linker, .-dyna_linker) @@ -118,6 +119,7 @@ FUNCTION(cc_interrupt): bne 2f ret 2: + ldr x1, [rFP, #LO_hash_table_ptr] bl ndrc_get_addr_ht br x0 ESIZE(cc_interrupt, .-cc_interrupt) @@ -173,6 +175,7 @@ FUNCTION(jump_to_new_pc): sub rCC, rCC, w1 str w1, [rFP, #LO_last_count] cbnz w2, new_dyna_leave + ldr x1, [rFP, #LO_hash_table_ptr] bl ndrc_get_addr_ht br x0 ESIZE(jump_to_new_pc, .-jump_to_new_pc) @@ -188,8 +191,9 @@ FUNCTION(new_dyna_start): stp x29, x30, [sp, #-SSP_ALL]! mov rFP, x0 ldr w0, [rFP, #LO_pcaddr] + ldr x1, [rFP, #LO_hash_table_ptr] bl ndrc_get_addr_ht - mov x1, x0 + mov x1, x0 new_dyna_start_at_e: ldr w3, [rFP, #LO_next_interupt] ldr w2, [rFP, #LO_cycle] diff --git a/libpcsxcore/new_dynarec/linkage_offsets.h b/libpcsxcore/new_dynarec/linkage_offsets.h index 2f0de6af..183afd1d 100644 --- a/libpcsxcore/new_dynarec/linkage_offsets.h +++ b/libpcsxcore/new_dynarec/linkage_offsets.h @@ -38,8 +38,8 @@ #define LO_psxH_ptr (LO_mem_wtab + PTRSZ) #define LO_zeromem_ptr (LO_psxH_ptr + PTRSZ) #define LO_invc_ptr (LO_zeromem_ptr + PTRSZ) -#define LO_scratch_buf_ptr (LO_invc_ptr + PTRSZ) -#define LO_saved_lr (LO_scratch_buf_ptr + PTRSZ) +#define LO_hash_table_ptr (LO_invc_ptr + PTRSZ) +#define LO_saved_lr (LO_hash_table_ptr + PTRSZ) #define LO_ram_offset (LO_saved_lr + PTRSZ) #define LO_mini_ht (LO_ram_offset + PTRSZ) #define LO_dynarec_local_size (LO_mini_ht + PTRSZ*32*2) diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index 87a82d01..e19e4361 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -75,6 +75,7 @@ extern int last_count; // last absolute target, often = next_interupt extern int reg_cop2d[], reg_cop2c[]; +extern void *hash_table_ptr; extern uintptr_t ram_offset; extern uintptr_t mini_ht[32][2]; @@ -400,7 +401,7 @@ void jump_to_new_pc(); void call_gteStall(); void new_dyna_leave(); -void *ndrc_get_addr_ht(u_int vaddr); +void *ndrc_get_addr_ht(u_int vaddr, struct ht_entry *ht); void ndrc_add_jump_out(u_int vaddr, void *src); void ndrc_write_invalidate_one(u_int addr); static void ndrc_write_invalidate_many(u_int addr, u_int end); @@ -642,9 +643,14 @@ static u_int get_page_prev(u_int vaddr) return page; } +static struct ht_entry *hash_table_get_p(struct ht_entry *ht, u_int vaddr) +{ + return &ht[((vaddr >> 16) ^ vaddr) & 0xFFFF]; +} + static struct ht_entry *hash_table_get(u_int vaddr) { - return &hash_table[((vaddr>>16)^vaddr)&0xFFFF]; + return hash_table_get_p(hash_table, vaddr); } #define HASH_TABLE_BAD 0xbac @@ -805,7 +811,8 @@ static noinline u_int generate_exception(u_int pc) // Get address from virtual address // This is called from the recompiled JR/JALR instructions -static void noinline *get_addr(const u_int vaddr, enum ndrc_compile_mode compile_mode) +static void noinline *get_addr(struct ht_entry *ht, const u_int vaddr, + enum ndrc_compile_mode compile_mode) { u_int start_page = get_page_prev(vaddr); u_int i, page, end_page = get_page(vaddr); @@ -846,31 +853,32 @@ static void noinline *get_addr(const u_int vaddr, enum ndrc_compile_mode compile int r = new_recompile_block(vaddr); if (likely(r == 0)) - return ndrc_get_addr_ht(vaddr); + return ndrc_get_addr_ht(vaddr, ht); if (compile_mode == ndrc_cm_compile_live) - return ndrc_get_addr_ht(generate_exception(vaddr)); + return ndrc_get_addr_ht(generate_exception(vaddr), ht); return NULL; } // Look up address in hash table first -void *ndrc_get_addr_ht_param(unsigned int vaddr, enum ndrc_compile_mode compile_mode) +void *ndrc_get_addr_ht_param(struct ht_entry *ht, unsigned int vaddr, + enum ndrc_compile_mode compile_mode) { //check_for_block_changes(vaddr, vaddr + MAXBLOCK); - const struct ht_entry *ht_bin = hash_table_get(vaddr); + const struct ht_entry *ht_bin = hash_table_get_p(ht, vaddr); u_int vaddr_a = vaddr & ~3; stat_inc(stat_ht_lookups); if (ht_bin->vaddr[0] == vaddr_a) return ht_bin->tcaddr[0]; if (ht_bin->vaddr[1] == vaddr_a) return ht_bin->tcaddr[1]; - return get_addr(vaddr, compile_mode); + return get_addr(ht, vaddr, compile_mode); } // "usual" addr lookup for indirect branches, etc // to be used by currently running code only -void *ndrc_get_addr_ht(u_int vaddr) +void *ndrc_get_addr_ht(u_int vaddr, struct ht_entry *ht) { - return ndrc_get_addr_ht_param(vaddr, ndrc_cm_compile_live); + return ndrc_get_addr_ht_param(ht, vaddr, ndrc_cm_compile_live); } static void clear_all_regs(signed char regmap[]) @@ -1317,6 +1325,7 @@ static const char *fpofs_name(u_int ofs) ofscase(psxH_ptr); ofscase(invc_ptr); ofscase(ram_offset); + ofscase(hash_table_ptr); #undef ofscase } buf[0] = 0; @@ -3439,9 +3448,10 @@ static void store_assemble(int i, const struct regstat *i_regs, int ccadj_) if(i_regs->regmap==regs[i].regmap) { load_all_consts(regs[i].regmap_entry,regs[i].wasdirty,i); wb_dirtys(regs[i].regmap_entry,regs[i].wasdirty); - emit_movimm(start+i*4+4,0); - emit_writeword(0,&psxRegs.pc); - emit_addimm(HOST_CCREG,2,HOST_CCREG); + emit_readptr(&hash_table_ptr, 1); + emit_movimm(start+i*4+4, 0); + emit_writeword(0, &psxRegs.pc); + emit_addimm(HOST_CCREG, 2, HOST_CCREG); emit_far_call(ndrc_get_addr_ht); emit_jmpreg(0); } @@ -3620,6 +3630,7 @@ static void cop0_assemble(int i, const struct regstat *i_regs, int ccadj_) emit_cmp(HOST_TEMPREG, 0); void *jaddr = out; emit_jeq(0); + emit_readptr(&hash_table_ptr, 1); emit_far_call(ndrc_get_addr_ht); emit_jmpreg(0); set_jump_target(jaddr, out); @@ -6368,6 +6379,7 @@ void new_dynarec_init(void) #endif out = ndrc->translation_cache; new_dynarec_clear_full(); + hash_table_ptr = hash_table; #ifdef HOST_IMM8 // Copy this into local area so we don't have to put it in every literal pool invc_ptr=invalid_code; @@ -6542,7 +6554,7 @@ void new_dynarec_load_blocks(const void *save, int size) psxRegs.GPR.r[i] = 0x1f800000; } - ndrc_get_addr_ht_param(sblocks[b].addr, ndrc_cm_compile_offline); + ndrc_get_addr_ht_param(hash_table, sblocks[b].addr, ndrc_cm_compile_offline); for (f = sblocks[b].regflags, i = 0; f; f >>= 1, i++) { if (f & 1) @@ -9038,6 +9050,7 @@ static int new_recompile_block(u_int addr) emit_addimm(0, 0x18, 0); emit_adds_ptr(1, 1, 1); emit_ldr_dualindexed(1, 0, 0); + emit_readptr(&hash_table_ptr, 1); emit_writeword(0, &psxRegs.GPR.r[26]); // lw k0, 0x18(sp) emit_far_call(ndrc_get_addr_ht); emit_jmpreg(0); // jr k0 diff --git a/libpcsxcore/new_dynarec/new_dynarec.h b/libpcsxcore/new_dynarec/new_dynarec.h index dcfc4215..411d8678 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.h +++ b/libpcsxcore/new_dynarec/new_dynarec.h @@ -44,12 +44,14 @@ void new_dynarec_invalidate_all_pages(void); void new_dyna_start(void *context); void new_dyna_start_at(void *context, void *compiled_code); +struct ht_entry; enum ndrc_compile_mode { ndrc_cm_no_compile = 0, ndrc_cm_compile_live, // from executing code, vaddr is the current pc ndrc_cm_compile_offline, ndrc_cm_compile_in_thread, }; -void *ndrc_get_addr_ht_param(unsigned int vaddr, enum ndrc_compile_mode compile_mode); +void *ndrc_get_addr_ht_param(struct ht_entry *ht, unsigned int vaddr, + enum ndrc_compile_mode compile_mode); extern unsigned int ndrc_smrv_regs[32];