From c87406ff726aa6ca927e3e73831a09a9ccb0667d Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 25 Oct 2024 02:29:53 +0300 Subject: [PATCH] move more globals to psxRegs more locality, less literal pools on ARM --- frontend/libretro.c | 6 +- frontend/main.c | 6 +- frontend/main.h | 12 --- frontend/plugin_lib.c | 13 ++- libpcsxcore/lightrec/plugin.c | 20 ++-- libpcsxcore/misc.c | 2 + libpcsxcore/new_dynarec/emu_if.c | 120 +++++++++++----------- libpcsxcore/new_dynarec/emu_if.h | 5 +- libpcsxcore/new_dynarec/linkage_arm.S | 9 +- libpcsxcore/new_dynarec/linkage_arm64.S | 9 +- libpcsxcore/new_dynarec/linkage_offsets.h | 23 +++-- libpcsxcore/new_dynarec/new_dynarec.c | 36 +++---- libpcsxcore/new_dynarec/new_dynarec.h | 2 - libpcsxcore/psxbios.c | 10 +- libpcsxcore/psxevents.c | 43 +++++--- libpcsxcore/psxevents.h | 12 +-- libpcsxcore/psxinterpreter.c | 42 +++----- libpcsxcore/psxinterpreter.h | 9 +- libpcsxcore/r3000a.c | 2 +- libpcsxcore/r3000a.h | 19 ++-- 20 files changed, 200 insertions(+), 200 deletions(-) diff --git a/frontend/libretro.c b/frontend/libretro.c index c932625f..3edcc2c9 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -659,7 +659,7 @@ struct rearmed_cbs pl_rearmed_cbs = { void pl_frame_limit(void) { /* called once per frame, make psxCpu->Execute() above return */ - stop++; + psxRegs.stop++; } void pl_timing_prepare(int is_pal) @@ -3288,8 +3288,8 @@ void retro_run(void) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) update_variables(true); - stop = 0; - psxCpu->Execute(); + psxRegs.stop = 0; + psxCpu->Execute(&psxRegs); if (pl_rearmed_cbs.fskip_dirty == 1) { if (frameskip_counter < frameskip_interval) diff --git a/frontend/main.c b/frontend/main.c index 3ead1b08..48006a67 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -538,7 +538,7 @@ int emu_core_init(void) void emu_core_ask_exit(void) { - stop++; + psxRegs.stop++; g_emu_want_quit = 1; } @@ -734,10 +734,10 @@ int main(int argc, char *argv[]) while (!g_emu_want_quit) { - stop = 0; + psxRegs.stop = 0; emu_action = SACTION_NONE; - psxCpu->Execute(); + psxCpu->Execute(&psxRegs); if (emu_action != SACTION_NONE) do_emu_action(); } diff --git a/frontend/main.h b/frontend/main.h index 98b0f370..1c249354 100644 --- a/frontend/main.h +++ b/frontend/main.h @@ -84,16 +84,4 @@ enum sched_action { #define SACTION_GUN_MASK (0x0f << SACTION_GUN_TRIGGER) -static inline void emu_set_action(enum sched_action action_) -{ - extern enum sched_action emu_action, emu_action_old; - extern int stop; - - if (action_ == SACTION_NONE) - emu_action_old = 0; - else if (action_ != emu_action_old) - stop++; - emu_action = action_; -} - #endif /* __FRONTEND_MAIN_H__ */ diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index 1b63f241..e12a7981 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -610,6 +610,17 @@ static void update_analogs(void) } } +static void emu_set_action(enum sched_action action_) +{ + extern enum sched_action emu_action, emu_action_old; + + if (action_ == SACTION_NONE) + emu_action_old = 0; + else if (action_ != emu_action_old) + psxRegs.stop++; + emu_action = action_; +} + static void update_input(void) { int actions[IN_BINDTYPE_COUNT] = { 0, }; @@ -834,7 +845,7 @@ static void *watchdog_thread(void *unused) { sleep(sleep_time); - if (stop) { + if (psxRegs.stop) { seen_dead = 0; sleep_time = 5; continue; diff --git a/libpcsxcore/lightrec/plugin.c b/libpcsxcore/lightrec/plugin.c index 7f500fd2..d62f35bd 100644 --- a/libpcsxcore/lightrec/plugin.c +++ b/libpcsxcore/lightrec/plugin.c @@ -69,8 +69,9 @@ void* code_buffer; static struct lightrec_state *lightrec_state; static bool use_lightrec_interpreter; -static bool use_pcsx_interpreter; static bool block_stepping; +//static bool use_pcsx_interpreter; +#define use_pcsx_interpreter 0 extern u32 lightrec_hacks; @@ -161,7 +162,7 @@ static void lightrec_tansition_to_pcsx(struct lightrec_state *state) static void lightrec_tansition_from_pcsx(struct lightrec_state *state) { - s32 cycles_left = next_interupt - psxRegs.cycle; + s32 cycles_left = psxRegs.next_interupt - psxRegs.cycle; if (block_stepping || cycles_left <= 0 || has_interrupt()) lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); @@ -490,10 +491,10 @@ static void lightrec_plugin_execute_internal(bool block_only) regs = lightrec_get_registers(lightrec_state); gen_interupt((psxCP0Regs *)regs->cp0); - if (!block_only && stop) + if (!block_only && psxRegs.stop) return; - cycles_pcsx = next_interupt - psxRegs.cycle; + cycles_pcsx = psxRegs.next_interupt - psxRegs.cycle; assert((s32)cycles_pcsx > 0); // step during early boot so that 0x80030000 fastboot hack works @@ -502,7 +503,7 @@ static void lightrec_plugin_execute_internal(bool block_only) cycles_pcsx = 0; if (use_pcsx_interpreter) { - intExecuteBlock(0); + psxInt.ExecuteBlock(&psxRegs, 0); } else { u32 cycles_lightrec = cycles_pcsx * 1024; if (unlikely(use_lightrec_interpreter)) { @@ -548,13 +549,14 @@ static void lightrec_plugin_execute_internal(bool block_only) } } -static void lightrec_plugin_execute(void) +static void lightrec_plugin_execute(psxRegisters *regs) { - while (!stop) + while (!regs->stop) lightrec_plugin_execute_internal(false); } -static void lightrec_plugin_execute_block(enum blockExecCaller caller) +static void lightrec_plugin_execute_block(psxRegisters *regs, + enum blockExecCaller caller) { lightrec_plugin_execute_internal(true); } @@ -603,6 +605,8 @@ static void lightrec_plugin_apply_config() } cycles_per_op_old = cycles_per_op; lightrec_set_cycles_per_opcode(lightrec_state, cycles_per_op); + + intApplyConfig(); } static void lightrec_plugin_shutdown(void) diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c index 28651025..6ba8d72c 100644 --- a/libpcsxcore/misc.c +++ b/libpcsxcore/misc.c @@ -779,7 +779,9 @@ int LoadState(const char *file) { SaveFuncs.read(f, psxH, 0x00010000); SaveFuncs.read(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle)); psxRegs.gteBusyCycle = psxRegs.cycle; + psxRegs.branching = 0; psxRegs.biosBranchCheck = ~0; + psxRegs.cpuInRecursion = 0; psxRegs.gpuIdleAfter = psxRegs.cycle - 1; HW_GPU_STATUS &= SWAP32(~PSXGPU_nBUSY); if (misc->magic == MISC_MAGIC) { diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index 98689998..8ebf2746 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -35,30 +35,8 @@ //#define evprintf printf #define evprintf(...) -#if !defined(DRC_DISABLE) && !defined(LIGHTREC) -// reduce global loads/literal pools (maybe) -#include "linkage_offsets.h" -#define dynarec_local_var4(x) dynarec_local[(x) / sizeof(dynarec_local[0])] -#define stop dynarec_local_var4(LO_stop) -#define psxRegs (*(psxRegisters *)((char *)dynarec_local + LO_psxRegs)) -#define next_interupt dynarec_local_var4(LO_next_interupt) -#endif - static void ari64_thread_sync(void); -void pcsx_mtc0(u32 reg, u32 val) -{ - evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle); - MTC0(&psxRegs, reg, val); - gen_interupt(&psxRegs.CP0); -} - -void pcsx_mtc0_ds(u32 reg, u32 val) -{ - evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle); - MTC0(&psxRegs, reg, val); -} - void ndrc_freeze(void *f, int mode) { const char header_save[8] = "ariblks"; @@ -111,10 +89,24 @@ void ndrc_clear_full(void) } #if !defined(DRC_DISABLE) && !defined(LIGHTREC) +#include "linkage_offsets.h" static void ari64_thread_init(void); static int ari64_thread_check_range(unsigned int start, unsigned int end); +void pcsx_mtc0(psxRegisters *regs, u32 reg, u32 val) +{ + evprintf("MTC0 %d #%x @%08x %u\n", reg, val, regs->pc, regs->cycle); + MTC0(regs, reg, val); + gen_interupt(®s->CP0); +} + +void pcsx_mtc0_ds(psxRegisters *regs, u32 reg, u32 val) +{ + evprintf("MTC0 %d #%x @%08x %u\n", reg, val, regs->pc, regs->cycle); + MTC0(regs, reg, val); +} + /* GTE stuff */ void *gte_handlers[64]; @@ -226,36 +218,39 @@ static void ari64_reset() // execute until predefined leave points // (HLE softcall exit and BIOS fastboot end) -static void ari64_execute_until() +static void ari64_execute_until(psxRegisters *regs) { - evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc, - psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle); + void *drc_local = (char *)regs - LO_psxRegs; + + assert(drc_local == dynarec_local); + evprintf("ari64_execute %08x, %u->%u (%d)\n", regs->pc, + regs->cycle, regs->next_interupt, regs->next_interupt - regs->cycle); - new_dyna_start(dynarec_local); + new_dyna_start(drc_local); - evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc, - psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle); + evprintf("ari64_execute end %08x, %u->%u (%d)\n", regs->pc, + regs->cycle, regs->next_interupt, regs->next_interupt - regs->cycle); } -static void ari64_execute() +static void ari64_execute(struct psxRegisters *regs) { - while (!stop) { - schedule_timeslice(); - ari64_execute_until(); - evprintf("drc left @%08x\n", psxRegs.pc); + while (!regs->stop) { + schedule_timeslice(regs); + ari64_execute_until(regs); + evprintf("drc left @%08x\n", regs->pc); } } -static void ari64_execute_block(enum blockExecCaller caller) +static void ari64_execute_block(struct psxRegisters *regs, enum blockExecCaller caller) { if (caller == EXEC_CALLER_BOOT) - stop++; + regs->stop++; - next_interupt = psxRegs.cycle + 1; - ari64_execute_until(); + regs->next_interupt = regs->cycle + 1; + ari64_execute_until(regs); if (caller == EXEC_CALLER_BOOT) - stop--; + regs->stop--; } static void ari64_clear(u32 addr, u32 size) @@ -332,12 +327,13 @@ static void clear_local_cache(void) #endif } -static noinline void ari64_execute_threaded_slow(enum blockExecCaller block_caller) +static noinline void ari64_execute_threaded_slow(struct psxRegisters *regs, + enum blockExecCaller block_caller) { if (!ndrc_g.thread.busy) { - memcpy(ndrc_smrv_regs, psxRegs.GPR.r, sizeof(ndrc_smrv_regs)); + memcpy(ndrc_smrv_regs, regs->GPR.r, sizeof(ndrc_smrv_regs)); slock_lock(ndrc_g.thread.lock); - ndrc_g.thread.addr = psxRegs.pc; + ndrc_g.thread.addr = regs->pc; ndrc_g.thread.busy = 1; slock_unlock(ndrc_g.thread.lock); scond_signal(ndrc_g.thread.cond); @@ -347,18 +343,19 @@ static noinline void ari64_execute_threaded_slow(enum blockExecCaller block_call psxInt.Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL); do { - psxInt.ExecuteBlock(block_caller); + psxInt.ExecuteBlock(regs, block_caller); } - while (!stop && ndrc_g.thread.busy && block_caller == EXEC_CALLER_OTHER); + while (!regs->stop && ndrc_g.thread.busy && block_caller == EXEC_CALLER_OTHER); psxInt.Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, NULL); //ari64_notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL); ari64_on_ext_change(0, 1); } -static void ari64_execute_threaded_once(enum blockExecCaller block_caller) +static void ari64_execute_threaded_once(struct psxRegisters *regs, + enum blockExecCaller block_caller) { - psxRegisters *regs = (void *)((char *)dynarec_local + LO_psxRegs); + void *drc_local = (char *)regs - LO_psxRegs; void *target; if (likely(!ndrc_g.thread.busy)) { @@ -366,35 +363,36 @@ static void ari64_execute_threaded_once(enum blockExecCaller block_caller) target = ndrc_get_addr_ht_param(regs->pc, ndrc_cm_no_compile); if (target) { clear_local_cache(); - new_dyna_start_at(dynarec_local, target); + new_dyna_start_at(drc_local, target); return; } } - ari64_execute_threaded_slow(block_caller); + ari64_execute_threaded_slow(regs, block_caller); } -static void ari64_execute_threaded() +static void ari64_execute_threaded(struct psxRegisters *regs) { - schedule_timeslice(); - while (!stop) + schedule_timeslice(regs); + while (!regs->stop) { - ari64_execute_threaded_once(EXEC_CALLER_OTHER); + ari64_execute_threaded_once(regs, EXEC_CALLER_OTHER); - if ((s32)(psxRegs.cycle - next_interupt) >= 0) - schedule_timeslice(); + if ((s32)(regs->cycle - regs->next_interupt) >= 0) + schedule_timeslice(regs); } } -static void ari64_execute_threaded_block(enum blockExecCaller caller) +static void ari64_execute_threaded_block(struct psxRegisters *regs, + enum blockExecCaller caller) { if (caller == EXEC_CALLER_BOOT) - stop++; + regs->stop++; - next_interupt = psxRegs.cycle + 1; - ari64_execute_threaded_once(caller); + regs->next_interupt = regs->cycle + 1; + ari64_execute_threaded_once(regs, caller); if (caller == EXEC_CALLER_BOOT) - stop--; + regs->stop--; } static void ari64_thread_sync(void) @@ -574,9 +572,6 @@ R3000Acpu psxRec = { #else // if DRC_DISABLE struct ndrc_globals ndrc_g; // dummy -unsigned int address; -int stop; -u32 next_interupt; void *psxH_ptr; void *zeromem_ptr; u32 zero_mem[0x1000/4]; @@ -861,7 +856,8 @@ void do_insn_cmp(void) for (i = 0; i < 8; i++) printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i], i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]); - printf("PC: %08x/%08x, cycle %u, next %u\n", psxRegs.pc, ppc, psxRegs.cycle, next_interupt); + printf("PC: %08x/%08x, cycle %u, next %u\n", psxRegs.pc, ppc, + psxRegs.cycle, psxRegs.next_interupt); //dump_mem("/tmp/psxram.dump", psxM, 0x200000); //dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000); exit(1); diff --git a/libpcsxcore/new_dynarec/emu_if.h b/libpcsxcore/new_dynarec/emu_if.h index 433455b1..03440c49 100644 --- a/libpcsxcore/new_dynarec/emu_if.h +++ b/libpcsxcore/new_dynarec/emu_if.h @@ -69,8 +69,9 @@ extern u32 inv_code_start, inv_code_end; extern u32 next_interupt; /* called by drc */ -void pcsx_mtc0(u32 reg, u32 val); -void pcsx_mtc0_ds(u32 reg, u32 val); +struct psxRegisters; +void pcsx_mtc0(struct psxRegisters *regs, u32 reg, u32 val); +void pcsx_mtc0_ds(struct psxRegisters *regs, u32 reg, u32 val); /* misc */ extern void SysPrintf(const char *fmt, ...); diff --git a/libpcsxcore/new_dynarec/linkage_arm.S b/libpcsxcore/new_dynarec/linkage_arm.S index bac1f299..1d8880ae 100644 --- a/libpcsxcore/new_dynarec/linkage_arm.S +++ b/libpcsxcore/new_dynarec/linkage_arm.S @@ -53,24 +53,19 @@ dynarec_local: #define DRC_VAR(name, size_) \ DRC_VAR_(name, ESYM(name), size_) -DRC_VAR(next_interupt, 4) +@DRC_VAR(next_interupt, 4) DRC_VAR(cycle_count, 4) DRC_VAR(last_count, 4) -@DRC_VAR(unused1, 4) -DRC_VAR(stop, 4) -DRC_VAR(branch_target, 4) +@DRC_VAR(stop, 4) DRC_VAR(address, 4) DRC_VAR(hack_addr, 4) DRC_VAR(psxRegs, LO_psxRegs_end - LO_psxRegs) /* psxRegs */ -@DRC_VAR(reg, 128) @DRC_VAR(lo, 4) @DRC_VAR(hi, 4) -DRC_VAR(reg_cop0, 128) DRC_VAR(reg_cop2d, 128) DRC_VAR(reg_cop2c, 128) -DRC_VAR(pcaddr, 4) @DRC_VAR(code, 4) @DRC_VAR(cycle, 4) @DRC_VAR(interrupt, 4) diff --git a/libpcsxcore/new_dynarec/linkage_arm64.S b/libpcsxcore/new_dynarec/linkage_arm64.S index 9e38bb96..155e0e2f 100644 --- a/libpcsxcore/new_dynarec/linkage_arm64.S +++ b/libpcsxcore/new_dynarec/linkage_arm64.S @@ -55,24 +55,19 @@ dynarec_local: #define DRC_VAR(name, size_) \ DRC_VAR_(name, ESYM(name), size_) -DRC_VAR(next_interupt, 4) +#DRC_VAR(next_interupt, 4) DRC_VAR(cycle_count, 4) DRC_VAR(last_count, 4) -@DRC_VAR(unused1, 4) -DRC_VAR(stop, 4) -DRC_VAR(branch_target, 4) +#DRC_VAR(stop, 4) DRC_VAR(address, 4) DRC_VAR(hack_addr, 4) DRC_VAR(psxRegs, LO_psxRegs_end - LO_psxRegs) /* psxRegs */ -#DRC_VAR(reg, 128) #DRC_VAR(lo, 4) #DRC_VAR(hi, 4) -DRC_VAR(reg_cop0, 128) DRC_VAR(reg_cop2d, 128) DRC_VAR(reg_cop2c, 128) -DRC_VAR(pcaddr, 4) #DRC_VAR(code, 4) #DRC_VAR(cycle, 4) #DRC_VAR(interrupt, 4) diff --git a/libpcsxcore/new_dynarec/linkage_offsets.h b/libpcsxcore/new_dynarec/linkage_offsets.h index 75521aa8..2f0de6af 100644 --- a/libpcsxcore/new_dynarec/linkage_offsets.h +++ b/libpcsxcore/new_dynarec/linkage_offsets.h @@ -1,17 +1,16 @@ #define PTRSZ __SIZEOF_POINTER__ -#define LO_next_interupt 64 -#define LO_cycle_count (LO_next_interupt + 4) +#define LO_unused0 64 +#define LO_unused1 (LO_unused0 + 4) +#define LO_unused2 (LO_unused1 + 4) +#define LO_unused3 (LO_unused2 + 4) +#define LO_cycle_count (LO_unused3 + 4) #define LO_last_count (LO_cycle_count + 4) -#define LO_unused1 (LO_last_count + 4) -#define LO_stop (LO_unused1 + 4) -#define LO_branch_target (LO_stop + 4) -#define LO_address (LO_branch_target + 4) +#define LO_address (LO_last_count + 4) #define LO_hack_addr (LO_address + 4) #define LO_psxRegs (LO_hack_addr + 4) -#define LO_reg (LO_psxRegs) -#define LO_lo (LO_reg + 128) +#define LO_lo (LO_psxRegs + 128) #define LO_hi (LO_lo + 4) #define LO_reg_cop0 (LO_hi + 4) #define LO_reg_cop2d (LO_reg_cop0 + 128) @@ -22,12 +21,14 @@ #define LO_cycle (LO_code + 4) #define LO_interrupt (LO_cycle + 4) #define LO_intCycle (LO_interrupt + 4) -#define LO_gteBusyCycle (LO_intCycle + 256) +#define LO_next_interupt (LO_intCycle + 4*2*31) +#define LO_unused4 (LO_next_interupt + 4) +#define LO_gteBusyCycle (LO_unused4 + 4) #define LO_muldivBusyCycle (LO_gteBusyCycle + 4) #define LO_psxRegs_subCycle (LO_muldivBusyCycle + 4) #define LO_psxRegs_biuReg (LO_psxRegs_subCycle + 4*2) -#define LO_psxRegs_reserved (LO_psxRegs_biuReg + 4) -#define LO_psxRegs_end (LO_psxRegs_reserved + 4*7) +#define LO_stop (LO_psxRegs_biuReg + 4) +#define LO_psxRegs_end (LO_stop + 4*7) #define LO_rcnts (LO_psxRegs_end) #define LO_rcnts_end (LO_rcnts + 7*4*4) #define LO_inv_code_start (LO_rcnts_end) diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c index bbf0d35b..87a82d01 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.c +++ b/libpcsxcore/new_dynarec/new_dynarec.c @@ -72,11 +72,7 @@ static Jit g_jit; // from linkage_* extern int cycle_count; // ... until end of the timeslice, counts -N -> 0 (CCREG) extern int last_count; // last absolute target, often = next_interupt -extern int pcaddr; -extern int branch_target; -/* same as psxRegs.CP0.n.* */ -extern int reg_cop0[]; extern int reg_cop2d[], reg_cop2c[]; extern uintptr_t ram_offset; @@ -3444,7 +3440,7 @@ static void store_assemble(int i, const struct regstat *i_regs, int ccadj_) 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,&pcaddr); + emit_writeword(0,&psxRegs.pc); emit_addimm(HOST_CCREG,2,HOST_CCREG); emit_far_call(ndrc_get_addr_ht); emit_jmpreg(0); @@ -3574,7 +3570,7 @@ static void cop0_assemble(int i, const struct regstat *i_regs, int ccadj_) signed char t=get_reg_w(i_regs->regmap, dops[i].rt1); u_int copr=(source[i]>>11)&0x1f; if(t>=0&&dops[i].rt1!=0) { - emit_readword(®_cop0[copr],t); + emit_readword(&psxRegs.CP0.r[copr],t); } } else if(dops[i].opcode2==4) // MTC0 @@ -3598,18 +3594,20 @@ static void cop0_assemble(int i, const struct regstat *i_regs, int ccadj_) emit_writeword(HOST_CCREG,&last_count); emit_movimm(0,HOST_CCREG); emit_storereg(CCREG,HOST_CCREG); - emit_loadreg(dops[i].rs1,1); - emit_movimm(copr,0); + emit_loadreg(dops[i].rs1, 2); + emit_movimm(copr, 1); + emit_addimm_ptr(FP, (u_char *)&psxRegs - (u_char *)&dynarec_local, 0); emit_far_call(pcsx_mtc0_ds); emit_loadreg(dops[i].rs1,s); return; } emit_movimm(start+i*4+4,HOST_TEMPREG); - emit_writeword(HOST_TEMPREG,&pcaddr); + emit_writeword(HOST_TEMPREG,&psxRegs.pc); } - if( s != 1) - emit_mov(s, 1); - emit_movimm(copr, 0); + if (s != 2) + emit_mov(s, 2); + emit_movimm(copr, 1); + emit_addimm_ptr(FP, (u_char *)&psxRegs - (u_char *)&dynarec_local, 0); emit_far_call(pcsx_mtc0); if (copr == 12 || copr == 13) { emit_readword(&psxRegs.cycle,HOST_CCREG); @@ -3617,7 +3615,7 @@ static void cop0_assemble(int i, const struct regstat *i_regs, int ccadj_) emit_sub(HOST_CCREG,HOST_TEMPREG,HOST_CCREG); //emit_writeword(HOST_TEMPREG,&last_count); assert(!is_delayslot); - emit_readword(&pcaddr, 0); + emit_readword(&psxRegs.pc, 0); emit_movimm(start+i*4+4, HOST_TEMPREG); emit_cmp(HOST_TEMPREG, 0); void *jaddr = out; @@ -5009,7 +5007,7 @@ static void drc_dbg_emit_do_cmp(int i, int ccadj_) emit_storereg(dops[i].rt1, 0); } emit_movimm(start+i*4,0); - emit_writeword(0,&pcaddr); + emit_writeword(0,&psxRegs.pc); int cc = get_reg(regs[i].regmap_entry, CCREG); if (cc < 0) emit_loadreg(CCREG, cc = 0); @@ -5296,7 +5294,7 @@ static void do_ccstub(int n) } else {SysPrintf("Unknown branch type in do_ccstub\n");abort();} } - emit_writeword(r_pc, &pcaddr); + emit_writeword(r_pc, &psxRegs.pc); // Update cycle count assert(branch_regs[i].regmap[HOST_CCREG]==CCREG||branch_regs[i].regmap[HOST_CCREG]==-1); if(stubs[n].a) emit_addimm(HOST_CCREG,(int)stubs[n].a,HOST_CCREG); @@ -5307,7 +5305,7 @@ static void do_ccstub(int n) load_needed_regs(branch_regs[i].regmap,regs[(cinfo[i].ba-start)>>2].regmap_entry); else if(dops[i].itype==RJUMP) { if(get_reg(branch_regs[i].regmap,RTEMP)>=0) - emit_readword(&pcaddr,get_reg(branch_regs[i].regmap,RTEMP)); + emit_readword(&psxRegs.pc,get_reg(branch_regs[i].regmap,RTEMP)); else emit_loadreg(dops[i].rs1,get_reg(branch_regs[i].regmap,dops[i].rs1)); } @@ -9020,7 +9018,7 @@ static int new_recompile_block(u_int addr) void *beginning = start_block(); emit_movimm(start,0); - emit_writeword(0,&pcaddr); + emit_writeword(0,&psxRegs.pc); emit_far_jump(new_dyna_leave); literal_pool(0); end_block(beginning); @@ -9134,13 +9132,13 @@ static int new_recompile_block(u_int addr) // for BiosBootBypass() to work // io address var abused as a "already been here" flag emit_readword(&address, 1); - emit_writeword(0, &pcaddr); + emit_writeword(0, &psxRegs.pc); emit_writeword(0, &address); emit_cmp(0, 1); } else { emit_readword(&psxRegs.cpuInRecursion, 1); - emit_writeword(0, &pcaddr); + emit_writeword(0, &psxRegs.pc); emit_test(1, 1); } #ifdef __aarch64__ diff --git a/libpcsxcore/new_dynarec/new_dynarec.h b/libpcsxcore/new_dynarec/new_dynarec.h index 5b27c86a..dcfc4215 100644 --- a/libpcsxcore/new_dynarec/new_dynarec.h +++ b/libpcsxcore/new_dynarec/new_dynarec.h @@ -2,8 +2,6 @@ #define MAXBLOCK 2048 // in mips instructions -extern int stop; - #define NDHACK_NO_SMC_CHECK (1<<0) #define NDHACK_GTE_UNNEEDED (1<<1) #define NDHACK_GTE_NO_FLAGS (1<<2) diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index 64a04b85..7682c92f 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -420,7 +420,7 @@ static inline void softCall(u32 pc) { psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, PTR_1); while (pc0 != 0x80001000 && ++lim < 0x100000) - psxCpu->ExecuteBlock(EXEC_CALLER_HLE); + psxCpu->ExecuteBlock(&psxRegs, EXEC_CALLER_HLE); psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, PTR_1); psxRegs.cpuInRecursion--; @@ -445,7 +445,7 @@ static inline void softCallInException(u32 pc) { psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, PTR_1); while (!returned_from_exception() && pc0 != 0x80001000 && ++lim < 0x100000) - psxCpu->ExecuteBlock(EXEC_CALLER_HLE); + psxCpu->ExecuteBlock(&psxRegs, EXEC_CALLER_HLE); psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, PTR_1); psxRegs.cpuInRecursion--; @@ -2270,8 +2270,8 @@ static void psxBios_WaitEvent() { // 0a // retrigger this hlecall after the next emulation event pc0 -= 4; - if ((s32)(next_interupt - psxRegs.cycle) > 0) - psxRegs.cycle = next_interupt; + if ((s32)(psxRegs.next_interupt - psxRegs.cycle) > 0) + psxRegs.cycle = psxRegs.next_interupt; psxBranchTest(); } @@ -4564,7 +4564,7 @@ void psxBiosCheckBranch(void) if (cycles_passed < 10 || cycles_passed > 50 || v0 != v0_expect) return; - waste_cycles = schedule_timeslice() - psxRegs.cycle; + waste_cycles = schedule_timeslice(&psxRegs) - psxRegs.cycle; loops = waste_cycles / cycles_passed; if (loops > v0) loops = v0; diff --git a/libpcsxcore/psxevents.c b/libpcsxcore/psxevents.c index 4d13cfb9..d90804ed 100644 --- a/libpcsxcore/psxevents.c +++ b/libpcsxcore/psxevents.c @@ -1,3 +1,4 @@ +#include #include #include "r3000a.h" #include "cdrom.h" @@ -10,10 +11,20 @@ u32 event_cycles[PSXINT_COUNT]; -u32 schedule_timeslice(void) +static psxRegisters *cp0TOpsxRegs(psxCP0Regs *cp0) { - u32 i, c = psxRegs.cycle; - u32 irqs = psxRegs.interrupt; +#ifndef LIGHTREC + return (void *)((char *)cp0 - offsetof(psxRegisters, CP0)); +#else + // lightrec has it's own cp0 + return &psxRegs; +#endif +} + +u32 schedule_timeslice(psxRegisters *regs) +{ + u32 i, c = regs->cycle; + u32 irqs = regs->interrupt; s32 min, dif; min = PSXCLK; @@ -25,8 +36,8 @@ u32 schedule_timeslice(void) if (0 < dif && dif < min) min = dif; } - next_interupt = c + min; - return next_interupt; + regs->next_interupt = c + min; + return regs->next_interupt; } static void irqNoOp() { @@ -55,15 +66,16 @@ static irq_func * const irq_funcs[] = { /* local dupe of psxBranchTest, using event_cycles */ void irq_test(psxCP0Regs *cp0) { - u32 cycle = psxRegs.cycle; + psxRegisters *regs = cp0TOpsxRegs(cp0); + u32 cycle = regs->cycle; u32 irq, irq_bits; - for (irq = 0, irq_bits = psxRegs.interrupt; irq_bits != 0; irq++, irq_bits >>= 1) { + for (irq = 0, irq_bits = regs->interrupt; irq_bits != 0; irq++, irq_bits >>= 1) { if (!(irq_bits & 1)) continue; if ((s32)(cycle - event_cycles[irq]) >= 0) { - // note: irq_funcs() also modify psxRegs.interrupt - psxRegs.interrupt &= ~(1u << irq); + // note: irq_funcs() also modify regs->interrupt + regs->interrupt &= ~(1u << irq); irq_funcs[irq](); } } @@ -77,15 +89,16 @@ void irq_test(psxCP0Regs *cp0) void gen_interupt(psxCP0Regs *cp0) { - evprintf(" +ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle, - next_interupt, next_interupt - psxRegs.cycle); + psxRegisters *regs = cp0TOpsxRegs(cp0); - irq_test(cp0); + evprintf(" +ge %08x, %u->%u (%d)\n", regs->pc, regs->cycle, + regs->next_interupt, regs->next_interupt - regs->cycle); - schedule_timeslice(); + irq_test(cp0); + schedule_timeslice(regs); - evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle, - next_interupt, next_interupt - psxRegs.cycle); + evprintf(" -ge %08x, %u->%u (%d)\n", regs->pc, regs->cycle, + regs->next_interupt, regs->next_interupt - regs->cycle); } void events_restore(void) diff --git a/libpcsxcore/psxevents.h b/libpcsxcore/psxevents.h index 1f1067ef..1a72c330 100644 --- a/libpcsxcore/psxevents.h +++ b/libpcsxcore/psxevents.h @@ -23,16 +23,14 @@ enum { }; extern u32 event_cycles[PSXINT_COUNT]; -extern u32 next_interupt; -extern int stop; #define set_event_raw_abs(e, abs) { \ u32 abs_ = abs; \ - s32 di_ = next_interupt - abs_; \ + s32 di_ = psxRegs.next_interupt - abs_; \ event_cycles[e] = abs_; \ if (di_ > 0) { \ - /*printf("%u: next_interupt %u -> %u\n", psxRegs.cycle, next_interupt, abs_);*/ \ - next_interupt = abs_; \ + /*printf("%u: next_interupt %u -> %u\n", psxRegs.cycle, psxRegs.next_interupt, abs_);*/ \ + psxRegs.next_interupt = abs_; \ } \ } @@ -44,7 +42,9 @@ extern int stop; } while (0) union psxCP0Regs_; -u32 schedule_timeslice(void); +struct psxRegisters; + +u32 schedule_timeslice(struct psxRegisters *regs); void irq_test(union psxCP0Regs_ *cp0); void gen_interupt(union psxCP0Regs_ *cp0); void events_restore(void); diff --git a/libpcsxcore/psxinterpreter.c b/libpcsxcore/psxinterpreter.c index fadbf050..c19f1c21 100644 --- a/libpcsxcore/psxinterpreter.c +++ b/libpcsxcore/psxinterpreter.c @@ -36,8 +36,6 @@ #define DO_EXCEPTION_RESERVEDI #define HANDLE_LOAD_DELAY -static int branchSeen = 0; - #ifdef __i386__ #define INT_ATTR __attribute__((regparm(2))) #else @@ -156,7 +154,7 @@ static void intExceptionDebugBp(psxRegisters *regs, u32 pc) cp0->n.Cause |= (regs->branching << 30) | (R3000E_Bp << 2); cp0->n.SR = (cp0->n.SR & ~0x3f) | ((cp0->n.SR & 0x0f) << 2); cp0->n.EPC = regs->branching ? pc - 4 : pc; - psxRegs.pc = 0x80000040; + regs->pc = 0x80000040; } static int execBreakCheck(psxRegisters *regs, u32 pc) @@ -412,7 +410,7 @@ static void psxDoDelayBranch(psxRegisters *regs, u32 tar1, u32 code1) { static void doBranch(psxRegisters *regs, u32 tar, enum R3000Abdt taken) { u32 code, pc, pc_final; - branchSeen = regs->branching = taken; + regs->branchSeen = regs->branching = taken; pc_final = taken == R3000A_BRANCH_TAKEN ? tar : regs->pc + 4; // fetch the delay slot @@ -1129,7 +1127,7 @@ OP(psxHLE) { } dloadFlush(regs_); psxHLEt[hleCode](); - branchSeen = 1; + regs_->branchSeen = 1; } static void (INT_ATTR *psxBSC[64])(psxRegisters *regs_, u32 code) = { @@ -1201,40 +1199,34 @@ static inline void execIbp(u8 **memRLUT, psxRegisters *regs) { psxBSC[regs->code >> 26](regs, regs->code); } -static void intExecute() { - psxRegisters *regs_ = &psxRegs; +static void intExecute(psxRegisters *regs) { u8 **memRLUT = psxMemRLUT; - extern int stop; - while (!stop) - execI_(memRLUT, regs_); + while (!regs->stop) + execI_(memRLUT, regs); } -static void intExecuteBp() { - psxRegisters *regs_ = &psxRegs; +static void intExecuteBp(psxRegisters *regs) { u8 **memRLUT = psxMemRLUT; - extern int stop; - while (!stop) - execIbp(memRLUT, regs_); + while (!regs->stop) + execIbp(memRLUT, regs); } -void intExecuteBlock(enum blockExecCaller caller) { - psxRegisters *regs_ = &psxRegs; +static void intExecuteBlock(psxRegisters *regs, enum blockExecCaller caller) { u8 **memRLUT = psxMemRLUT; - branchSeen = 0; - while (!branchSeen) - execI_(memRLUT, regs_); + regs->branchSeen = 0; + while (!regs->branchSeen) + execI_(memRLUT, regs); } -static void intExecuteBlockBp(enum blockExecCaller caller) { - psxRegisters *regs_ = &psxRegs; +static void intExecuteBlockBp(psxRegisters *regs, enum blockExecCaller caller) { u8 **memRLUT = psxMemRLUT; - branchSeen = 0; - while (!branchSeen) - execIbp(memRLUT, regs_); + regs->branchSeen = 0; + while (!regs->branchSeen) + execIbp(memRLUT, regs); } static void intClear(u32 Addr, u32 Size) { diff --git a/libpcsxcore/psxinterpreter.h b/libpcsxcore/psxinterpreter.h index 2c3f3943..bc219a49 100644 --- a/libpcsxcore/psxinterpreter.h +++ b/libpcsxcore/psxinterpreter.h @@ -1,17 +1,16 @@ #ifndef __PSXINTERPRETER_H__ #define __PSXINTERPRETER_H__ +struct psxRegisters; + // get an opcode without triggering exceptions or affecting cache u32 intFakeFetch(u32 pc); // called by "new_dynarec" -void execI(psxRegisters *regs); +void execI(struct psxRegisters *regs); void intApplyConfig(); -void MTC0(psxRegisters *regs_, int reg, u32 val); +void MTC0(struct psxRegisters *regs, int reg, u32 val); void gteNULL(struct psxCP2Regs *regs); extern void (*psxCP2[64])(struct psxCP2Regs *regs); -// called by lightrec -void intExecuteBlock(enum blockExecCaller caller); - #endif // __PSXINTERPRETER_H__ diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c index 0c29dba7..b1b819e4 100644 --- a/libpcsxcore/r3000a.c +++ b/libpcsxcore/r3000a.c @@ -169,7 +169,7 @@ void psxJumpTest() { void psxExecuteBios() { int i; for (i = 0; i < 5000000; i++) { - psxCpu->ExecuteBlock(EXEC_CALLER_BOOT); + psxCpu->ExecuteBlock(&psxRegs, EXEC_CALLER_BOOT); if ((psxRegs.pc & 0xff800000) == 0x80000000) break; } diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 93a53ced..025cfa44 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -52,11 +52,14 @@ enum blockExecCaller { EXEC_CALLER_OTHER, }; +struct psxRegisters; + typedef struct { int (*Init)(); void (*Reset)(); - void (*Execute)(); - void (*ExecuteBlock)(enum blockExecCaller caller); /* executes up to a jump */ + void (*Execute)(struct psxRegisters *regs); + /* executes up to a jump */ + void (*ExecuteBlock)(struct psxRegisters *regs, enum blockExecCaller caller); void (*Clear)(u32 Addr, u32 Size); void (*Notify)(enum R3000Anote note, void *data); void (*ApplyConfig)(); @@ -177,7 +180,7 @@ typedef struct psxCP2Regs { psxCP2Ctrl CP2C; /* Cop2 control registers */ } psxCP2Regs; -typedef struct { +typedef struct psxRegisters { // note: some cores like lightrec don't keep their data here, // so use R3000ACPU_NOTIFY_BEFORE_SAVE to sync psxGPRRegs GPR; /* General Purpose Registers */ @@ -193,22 +196,26 @@ typedef struct { u32 code; /* The instruction */ u32 cycle; u32 interrupt; - struct { u32 sCycle, cycle; } intCycle[32]; + struct { u32 sCycle, cycle; } intCycle[31]; + u32 next_interupt; /* cycle */ + u32 unused; u32 gteBusyCycle; u32 muldivBusyCycle; u32 subCycle; /* interpreter cycle counting */ u32 subCycleStep; u32 biuReg; + u8 stop; + u8 branchSeen; /* interp. */ u8 branching; /* interp. R3000A_BRANCH_TAKEN / not, 0 if not branch */ u8 dloadSel; /* interp. delay load state */ u8 dloadReg[2]; + u8 unused2[2]; u32 dloadVal[2]; u32 biosBranchCheck; u32 cpuInRecursion; u32 gpuIdleAfter; - u32 reserved[1]; // warning: changing anything in psxRegisters requires update of all - // asm in libpcsxcore/new_dynarec/ + // asm in libpcsxcore/new_dynarec/ and may break savestates } psxRegisters; extern psxRegisters psxRegs; -- 2.39.5