move more globals to psxRegs
authornotaz <notasas@gmail.com>
Thu, 24 Oct 2024 23:29:53 +0000 (02:29 +0300)
committernotaz <notasas@gmail.com>
Thu, 24 Oct 2024 23:52:05 +0000 (02:52 +0300)
more locality, less literal pools on ARM

20 files changed:
frontend/libretro.c
frontend/main.c
frontend/main.h
frontend/plugin_lib.c
libpcsxcore/lightrec/plugin.c
libpcsxcore/misc.c
libpcsxcore/new_dynarec/emu_if.c
libpcsxcore/new_dynarec/emu_if.h
libpcsxcore/new_dynarec/linkage_arm.S
libpcsxcore/new_dynarec/linkage_arm64.S
libpcsxcore/new_dynarec/linkage_offsets.h
libpcsxcore/new_dynarec/new_dynarec.c
libpcsxcore/new_dynarec/new_dynarec.h
libpcsxcore/psxbios.c
libpcsxcore/psxevents.c
libpcsxcore/psxevents.h
libpcsxcore/psxinterpreter.c
libpcsxcore/psxinterpreter.h
libpcsxcore/r3000a.c
libpcsxcore/r3000a.h

index c932625..3edcc2c 100644 (file)
@@ -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)
index 3ead1b0..48006a6 100644 (file)
@@ -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();
        }
index 98b0f37..1c24935 100644 (file)
@@ -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__ */
index 1b63f24..e12a798 100644 (file)
@@ -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;
index 7f500fd..d62f35b 100644 (file)
@@ -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)
index 2865102..6ba8d72 100644 (file)
@@ -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) {
index 9868999..8ebf274 100644 (file)
 //#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(&regs->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);
index 433455b..03440c4 100644 (file)
@@ -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, ...);
index bac1f29..1d8880a 100644 (file)
@@ -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)
index 9e38bb9..155e0e2 100644 (file)
@@ -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)
index 75521aa..2f0de6a 100644 (file)
@@ -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)
 #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)
index bbf0d35..87a82d0 100644 (file)
@@ -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(&reg_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__
index 5b27c86..dcfc421 100644 (file)
@@ -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)
index 64a04b8..7682c92 100644 (file)
@@ -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;
index 4d13cfb..d90804e 100644 (file)
@@ -1,3 +1,4 @@
+#include <stddef.h>
 #include <stdio.h>
 #include "r3000a.h"
 #include "cdrom.h"
 
 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)
index 1f1067e..1a72c33 100644 (file)
@@ -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);
index fadbf05..c19f1c2 100644 (file)
@@ -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) {
index 2c3f394..bc219a4 100644 (file)
@@ -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__
index 0c29dba..b1b819e 100644 (file)
@@ -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;
        }
index 93a53ce..025cfa4 100644 (file)
@@ -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;