summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriCatButler <i.am.catbutler@gmail.com>2016-08-05 12:40:42 +0100
committeriCatButler <i.am.catbutler@gmail.com>2016-08-05 12:40:42 +0100
commit36ef7277127e1010c296ce8792f74934c2ee9d2f (patch)
treec5cb422cac43c48d6a261e6d0077487d2d2a3d45
parent595034707b7ee346e575c6776327794ab5535ce8 (diff)
Add PGXP support to 64bit dynarec
- Copy over PGXP integration from 32bit version
-rw-r--r--libpcsxcore/ix86_64/iPGXP-64.h255
-rwxr-xr-xlibpcsxcore/ix86_64/iR3000A-64.c139
2 files changed, 384 insertions, 10 deletions
diff --git a/libpcsxcore/ix86_64/iPGXP-64.h b/libpcsxcore/ix86_64/iPGXP-64.h
new file mode 100644
index 00000000..69b3d775
--- /dev/null
+++ b/libpcsxcore/ix86_64/iPGXP-64.h
@@ -0,0 +1,255 @@
+#ifndef _I_PGXP_H_
+#define _I_PGXP_H_
+
+
+/////////////////////////////////////////////
+// PGXP wrapper functions
+/////////////////////////////////////////////
+
+pgxpRecNULL() {}
+
+// Choose between debug and direct function
+#ifdef PGXP_CPU_DEBUG
+#define PGXP_REC_FUNC_OP(pu, op, nReg) PGXP_psxTraceOp##nReg
+#define PGXP_DBG_OP_E(op) PUSH32I(DBG_E_##op); resp+=4;
+#else
+#define PGXP_REC_FUNC_OP(pu, op, nReg) PGXP_##pu##_##op
+#define PGXP_DBG_OP_E(op)
+#endif
+
+#define PGXP_REC_FUNC_PASS(pu, op) \
+static void pgxpRec##op() { \
+ rec##op();\
+}
+
+#define PGXP_REC_FUNC(pu, op) \
+static void pgxpRec##op() { \
+ PUSH32I(psxRegs.code); \
+ PGXP_DBG_OP_E(op) \
+ CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, )); \
+ resp += 4; \
+ rec##op();\
+}
+
+#define PGXP_REC_FUNC_1(pu, op, reg1) \
+static void pgxpRec##op() { \
+ reg1;\
+ PUSH32I(psxRegs.code); \
+ PGXP_DBG_OP_E(op) \
+ CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 1)); \
+ resp += 8; \
+ rec##op();\
+}
+
+#define PGXP_REC_FUNC_2_2(pu, op, test, nReg, reg1, reg2, reg3, reg4) \
+static void pgxpRec##op() { \
+ if(test) { rec##op(); return; }\
+ reg1;\
+ reg2;\
+ rec##op();\
+ reg3;\
+ reg4;\
+ PUSH32I(psxRegs.code); \
+ PGXP_DBG_OP_E(op) \
+ CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, nReg)); \
+ resp += (4 * nReg) + 4; \
+}
+
+#define PGXP_REC_FUNC_2(pu, op, reg1, reg2) \
+static void pgxpRec##op() { \
+ reg1;\
+ reg2;\
+ PUSH32I(psxRegs.code); \
+ PGXP_DBG_OP_E(op) \
+ CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 2)); \
+ resp += 12; \
+ rec##op();\
+}
+
+static u32 gTempAddr = 0;
+#define PGXP_REC_FUNC_ADDR_1(pu, op, reg1) \
+static void pgxpRec##op() \
+{ \
+ if (IsConst(_Rs_)) \
+ { \
+ MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_); \
+ } \
+ else\
+ {\
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);\
+ if (_Imm_)\
+ {\
+ ADD32ItoR(EAX, _Imm_);\
+ }\
+ }\
+ MOV32RtoM((u32)&gTempAddr, EAX);\
+ rec##op();\
+ PUSH64M((u32)&gTempAddr);\
+ reg1;\
+ PUSH32I(psxRegs.code); \
+ PGXP_DBG_OP_E(op) \
+ CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 2)); \
+ resp += 12; \
+}
+
+
+#define CPU_REG_NC(idx) MOV32MtoR(EAX,(u32)&psxRegs.GPR.r[idx])
+
+#define CPU_REG(idx) \
+ if (IsConst(idx)) \
+ MOV32ItoR(EAX, iRegs[idx].k); \
+ else\
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[idx]);
+
+#define CP0_REG(idx) MOV32MtoR(EAX,(u32)&psxRegs.CP0.r[idx])
+#define GTE_DATA_REG(idx) MOV32MtoR(EAX,(u32)&psxRegs.CP2D.r[idx])
+#define GTE_CTRL_REG(idx) MOV32MtoR(EAX,(u32)&psxRegs.CP2C.r[idx])
+
+static u32 gTempInstr = 0;
+static u32 gTempReg1 = 0;
+static u32 gTempReg2 = 0;
+#define PGXP_REC_FUNC_R1_1(pu, op, test, reg1, reg2) \
+static void pgxpRec##op() \
+{ \
+ if(test) { rec##op(); return; }\
+ reg1;\
+ MOV32RtoM((u32)&gTempReg1, EAX);\
+ rec##op();\
+ PUSH64M((u32)&gTempReg1);\
+ reg2;\
+ PUSH32I(psxRegs.code); \
+ PGXP_DBG_OP_E(op) \
+ CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 2)); \
+ resp += 12; \
+}
+
+#define PGXP_REC_FUNC_R2_1(pu, op, test, reg1, reg2, reg3) \
+static void pgxpRec##op() \
+{ \
+ if(test) { rec##op(); return; }\
+ reg1;\
+ MOV32RtoM((u32)&gTempReg1, EAX);\
+ reg2;\
+ MOV32RtoM((u32)&gTempReg2, EAX);\
+ rec##op();\
+ PUSH64M((u32)&gTempReg1);\
+ PUSH64M((u32)&gTempReg2);\
+ reg3;\
+ PUSH32I(psxRegs.code); \
+ PGXP_DBG_OP_E(op) \
+ CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 3)); \
+ resp += 16; \
+}
+
+#define PGXP_REC_FUNC_R2_2(pu, op, test, reg1, reg2, reg3, reg4) \
+static void pgxpRec##op() \
+{ \
+ if(test) { rec##op(); return; }\
+ reg1;\
+ MOV32RtoM((u32)&gTempReg1, EAX);\
+ reg2;\
+ MOV32RtoM((u32)&gTempReg2, EAX);\
+ rec##op();\
+ PUSH64M((u32)&gTempReg1);\
+ PUSH64M((u32)&gTempReg2);\
+ reg3;\
+ reg4;\
+ PUSH32I(psxRegs.code); \
+ PGXP_DBG_OP_E(op) \
+ CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 4)); \
+ resp += 20; \
+}
+
+//#define PGXP_REC_FUNC_R1i_1(pu, op, test, reg1, reg2) \
+//static void pgxpRec##op() \
+//{ \
+// if(test) { rec##op(); return; }\
+// if (IsConst(reg1)) \
+// MOV32ItoR(EAX, iRegs[reg1].k); \
+// else\
+// MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[reg1]);\
+// MOV32RtoM((u32)&gTempReg, EAX);\
+// rec##op();\
+// PUSH64M((u32)&gTempReg);\
+// reg2;\
+// PUSH32I(psxRegs.code); \
+// CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 2)); \
+// resp += 12; \
+//}
+
+// Rt = Rs op imm
+PGXP_REC_FUNC_R1_1(CPU, ADDI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(CPU, ADDIU, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(CPU, ANDI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(CPU, ORI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(CPU, XORI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(CPU, SLTI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(CPU, SLTIU, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
+
+// Rt = imm
+PGXP_REC_FUNC_2_2(CPU, LUI, !_Rt_, 1, , , iPushReg(_Rt_), )
+
+// Rd = Rs op Rt
+PGXP_REC_FUNC_R2_1(CPU, ADD, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, ADDU, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, SUB, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, SUBU, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, AND, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, OR, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, XOR, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, NOR, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, SLT, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, SLTU, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
+
+// Hi/Lo = Rs op Rt
+PGXP_REC_FUNC_R2_2(CPU, MULT, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH64M((u32)&psxRegs.GPR.n.lo), PUSH64M((u32)&psxRegs.GPR.n.hi))
+PGXP_REC_FUNC_R2_2(CPU, MULTU, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH64M((u32)&psxRegs.GPR.n.lo), PUSH64M((u32)&psxRegs.GPR.n.hi))
+PGXP_REC_FUNC_R2_2(CPU, DIV, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH64M((u32)&psxRegs.GPR.n.lo), PUSH64M((u32)&psxRegs.GPR.n.hi))
+PGXP_REC_FUNC_R2_2(CPU, DIVU, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH64M((u32)&psxRegs.GPR.n.lo), PUSH64M((u32)&psxRegs.GPR.n.hi))
+
+PGXP_REC_FUNC_ADDR_1(CPU, SB, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, SH, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, SW, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, SWL, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, SWR, iPushReg(_Rt_))
+
+PGXP_REC_FUNC_ADDR_1(CPU, LWL, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, LW, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, LWR, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, LH, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, LHU, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, LB, iPushReg(_Rt_))
+PGXP_REC_FUNC_ADDR_1(CPU, LBU, iPushReg(_Rt_))
+
+//Rd = Rt op Sa
+PGXP_REC_FUNC_R1_1(CPU, SLL, !_Rd_, CPU_REG(_Rt_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R1_1(CPU, SRL, !_Rd_, CPU_REG(_Rt_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R1_1(CPU, SRA, !_Rd_, CPU_REG(_Rt_), iPushReg(_Rd_))
+
+// Rd = Rt op Rs
+PGXP_REC_FUNC_R2_1(CPU, SLLV, !_Rd_, CPU_REG(_Rs_), CPU_REG(_Rt_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, SRLV, !_Rd_, CPU_REG(_Rs_), CPU_REG(_Rt_), iPushReg(_Rd_))
+PGXP_REC_FUNC_R2_1(CPU, SRAV, !_Rd_, CPU_REG(_Rs_), CPU_REG(_Rt_), iPushReg(_Rd_))
+
+PGXP_REC_FUNC_R1_1(CPU, MFHI, !_Rd_, CPU_REG_NC(33), iPushReg(_Rd_))
+PGXP_REC_FUNC_R1_1(CPU, MTHI, 0, CPU_REG(_Rd_), PUSH64M((u32)&psxRegs.GPR.n.hi))
+PGXP_REC_FUNC_R1_1(CPU, MFLO, !_Rd_, CPU_REG_NC(32), iPushReg(_Rd_))
+PGXP_REC_FUNC_R1_1(CPU, MTLO, 0, CPU_REG(_Rd_), PUSH64M((u32)&psxRegs.GPR.n.lo))
+
+// COP2 (GTE)
+PGXP_REC_FUNC_R1_1(GTE, MFC2, !_Rt_, GTE_DATA_REG(_Rd_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(GTE, CFC2, !_Rt_, GTE_CTRL_REG(_Rd_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(GTE, MTC2, 0, CPU_REG(_Rt_), PUSH64M((u32)&psxRegs.CP2D.r[_Rd_]))
+PGXP_REC_FUNC_R1_1(GTE, CTC2, 0, CPU_REG(_Rt_), PUSH64M((u32)&psxRegs.CP2C.r[_Rd_]))
+
+PGXP_REC_FUNC_ADDR_1(GTE, LWC2, PUSH64M((u32)&psxRegs.CP2D.r[_Rt_]))
+PGXP_REC_FUNC_ADDR_1(GTE, SWC2, PUSH64M((u32)&psxRegs.CP2D.r[_Rt_]))
+
+// COP0
+PGXP_REC_FUNC_R1_1(CP0, MFC0, !_Rd_, CP0_REG(_Rd_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(CP0, CFC0, !_Rd_, CP0_REG(_Rd_), iPushReg(_Rt_))
+PGXP_REC_FUNC_R1_1(CP0, MTC0, !_Rt_, CPU_REG(_Rt_), PUSH64M((u32)&psxRegs.CP0.r[_Rd_]))
+PGXP_REC_FUNC_R1_1(CP0, CTC0, !_Rt_, CPU_REG(_Rt_), PUSH64M((u32)&psxRegs.CP0.r[_Rd_]))
+PGXP_REC_FUNC(CP0, RFE)
+
+#endif//_I_PGXP_H_
diff --git a/libpcsxcore/ix86_64/iR3000A-64.c b/libpcsxcore/ix86_64/iR3000A-64.c
index 5c24142a..e1245987 100755
--- a/libpcsxcore/ix86_64/iR3000A-64.c
+++ b/libpcsxcore/ix86_64/iR3000A-64.c
@@ -27,6 +27,10 @@
#include "../r3000a.h"
#include "../psxhle.h"
+#include "pgxp_cpu.h"
+#include "pgxp_gte.h"
+#include "pgxp_debug.h"
+
#include <sys/mman.h>
#ifndef MAP_ANONYMOUS
@@ -81,6 +85,60 @@ static void (*recCP0[32])();
static void (*recCP2[64])();
static void (*recCP2BSC[32])();
+
+/// PGXP function tables
+static void(*pgxpRecBSC[64])();
+static void(*pgxpRecSPC[64])();
+static void(*pgxpRecCP0[32])();
+static void(*pgxpRecCP2BSC[32])();
+
+static void(*pgxpRecBSCMem[64])();
+///
+
+static void(**pRecBSC)() = recBSC;
+static void(**pRecSPC)() = recSPC;
+static void(**pRecREG)() = recREG;
+static void(**pRecCP0)() = recCP0;
+static void(**pRecCP2)() = recCP2;
+static void(**pRecCP2BSC)() = recCP2BSC;
+
+static void recReset();
+static void recSetPGXPMode(u32 pgxpMode)
+{
+ switch (pgxpMode)
+ {
+ case 0: //PGXP_MODE_DISABLED:
+ pRecBSC = recBSC;
+ pRecSPC = recSPC;
+ pRecREG = recREG;
+ pRecCP0 = recCP0;
+ pRecCP2 = recCP2;
+ pRecCP2BSC = recCP2BSC;
+ break;
+ case 1: //PGXP_MODE_MEM:
+ pRecBSC = pgxpRecBSCMem;
+ pRecSPC = recSPC;
+ pRecREG = recREG;
+ pRecCP0 = pgxpRecCP0;
+ pRecCP2 = recCP2;
+ pRecCP2BSC = pgxpRecCP2BSC;
+ break;
+ case 2: //PGXP_MODE_FULL:
+ pRecBSC = pgxpRecBSC;
+ pRecSPC = pgxpRecSPC;
+ pRecREG = recREG;
+ pRecCP0 = pgxpRecCP0;
+ pRecCP2 = recCP2;
+ pRecCP2BSC = pgxpRecCP2BSC;
+ break;
+ }
+
+ // set interpreter mode too
+ psxInt.SetPGXPMode(pgxpMode);
+ // reset to ensure new func tables are used
+ recReset();
+}
+
#define STACKSIZE 0x18
static void StackRes()
{
@@ -133,6 +191,16 @@ static void iFlushRegs() {
}
}
+static void iPushReg(int reg)
+{
+ if (IsConst(reg)) {
+ PUSH32I(iRegs[reg].k);
+ }
+ else {
+ PUSH64M((uptr)&psxRegs.GPR.r[reg]);
+ }
+}
+
static void iStoreCycle() {
count = ((pc - pcold) / 4) * BIAS;
ADD32ItoM((uptr)&psxRegs.cycle, count);
@@ -216,7 +284,7 @@ static void SetBranch() {
break;
default:
- recBSC[psxRegs.code>>26]();
+ pRecBSC[psxRegs.code>>26]();
break;
}
@@ -257,7 +325,7 @@ static void iJump(u32 branchPC) {
return;
}
- recBSC[psxRegs.code>>26]();
+ pRecBSC[psxRegs.code>>26]();
iFlushRegs();
iStoreCycle();
@@ -324,7 +392,7 @@ static void iBranch(u32 branchPC, int savectx) {
}
pc+= 4;
- recBSC[psxRegs.code>>26]();
+ pRecBSC[psxRegs.code>>26]();
iFlushRegs();
iStoreCycle();
@@ -566,16 +634,16 @@ static void recNULL() {
//REC_SYS(SPECIAL);
#if 1
static void recSPECIAL() {
- recSPC[_Funct_]();
+ pRecSPC[_Funct_]();
}
#endif
static void recREGIMM() {
- recREG[_Rt_]();
+ pRecREG[_Rt_]();
}
static void recCOP0() {
- recCP0[_Rs_]();
+ pRecCP0[_Rs_]();
}
//REC_SYS(COP2);
@@ -585,14 +653,14 @@ static void recCOP2() {
AND32ItoR(EAX, 0x40000000);
j32Ptr[31] = JZ32(0);
- recCP2[_Funct_]();
+ pRecCP2[_Funct_]();
x86SetJ32(j32Ptr[31]);
}
#endif
static void recBASIC() {
- recCP2BSC[_Rs_]();
+ pRecCP2BSC[_Rs_]();
}
//end of Tables opcodes...
@@ -2937,6 +3005,8 @@ static void recHLE() {
//
+#include "iPGXP-64.h"
+
static void (*recBSC[64])() = {
recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ,
recADDI , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI ,
@@ -2991,6 +3061,54 @@ static void (*recCP2BSC[32])() = {
recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
};
+// Trace all functions using PGXP
+static void(*pgxpRecBSC[64])() = {
+ recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ,
+ pgxpRecADDI , pgxpRecADDIU , pgxpRecSLTI, pgxpRecSLTIU, pgxpRecANDI, pgxpRecORI , pgxpRecXORI, pgxpRecLUI ,
+ recCOP0 , recNULL , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL,
+ pgxpRecLB , pgxpRecLH , pgxpRecLWL , pgxpRecLW , pgxpRecLBU , pgxpRecLHU , pgxpRecLWR , pgxpRecNULL,
+ pgxpRecSB , pgxpRecSH , pgxpRecSWL , pgxpRecSW , pgxpRecNULL, pgxpRecNULL, pgxpRecSWR , pgxpRecNULL,
+ recNULL , recNULL , pgxpRecLWC2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , pgxpRecSWC2, recHLE , recNULL, recNULL, recNULL, recNULL
+};
+
+static void(*pgxpRecSPC[64])() = {
+ pgxpRecSLL , pgxpRecNULL, pgxpRecSRL , pgxpRecSRA , pgxpRecSLLV , pgxpRecNULL , pgxpRecSRLV, pgxpRecSRAV,
+ recJR , recJALR, recNULL, recNULL, recSYSCALL, recBREAK, recNULL, recNULL,
+ pgxpRecMFHI, pgxpRecMTHI, pgxpRecMFLO, pgxpRecMTLO, pgxpRecNULL , pgxpRecNULL , pgxpRecNULL, pgxpRecNULL,
+ pgxpRecMULT, pgxpRecMULTU, pgxpRecDIV, pgxpRecDIVU, pgxpRecNULL , pgxpRecNULL , pgxpRecNULL, pgxpRecNULL,
+ pgxpRecADD , pgxpRecADDU, pgxpRecSUB , pgxpRecSUBU, pgxpRecAND , pgxpRecOR , pgxpRecXOR , pgxpRecNOR ,
+ pgxpRecNULL, pgxpRecNULL, pgxpRecSLT , pgxpRecSLTU, pgxpRecNULL , pgxpRecNULL , pgxpRecNULL, pgxpRecNULL,
+ pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL , pgxpRecNULL , pgxpRecNULL, pgxpRecNULL,
+ pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL , pgxpRecNULL , pgxpRecNULL, pgxpRecNULL
+};
+
+static void(*pgxpRecCP0[32])() = {
+ pgxpRecMFC0, pgxpRecNULL, pgxpRecCFC0, pgxpRecNULL, pgxpRecMTC0, pgxpRecNULL, pgxpRecCTC0, pgxpRecNULL,
+ pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL,
+ pgxpRecRFE , pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL,
+ pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL
+};
+
+static void(*pgxpRecCP2BSC[32])() = {
+ pgxpRecMFC2, pgxpRecNULL, pgxpRecCFC2, pgxpRecNULL, pgxpRecMTC2, pgxpRecNULL, pgxpRecCTC2, pgxpRecNULL,
+ pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL,
+ pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL,
+ pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL, pgxpRecNULL
+};
+
+// Trace memory functions only
+static void(*pgxpRecBSCMem[64])() = {
+ recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ,
+ recADDI , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI ,
+ recCOP0 , recNULL , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL,
+ pgxpRecLB , pgxpRecLH , pgxpRecLWL , pgxpRecLW , pgxpRecLBU , pgxpRecLHU , pgxpRecLWR , pgxpRecNULL,
+ pgxpRecSB , pgxpRecSH , pgxpRecSWL , pgxpRecSW , pgxpRecNULL, pgxpRecNULL, pgxpRecSWR , pgxpRecNULL,
+ recNULL , recNULL , pgxpRecLWC2, recNULL , recNULL, recNULL, recNULL, recNULL,
+ recNULL , recNULL , pgxpRecSWC2, recHLE , recNULL, recNULL, recNULL, recNULL
+};
static void recRecompile() {
char *p;
@@ -3061,7 +3179,7 @@ static void recRecompile() {
iDump(iRegs);
#endif
pc+=4; count++;
- recBSC[psxRegs.code>>26]();
+ pRecBSC[psxRegs.code>>26]();
#ifdef PSXCPU_LOG
dump = FALSE;
#endif
@@ -3087,6 +3205,7 @@ R3000Acpu psxRec = {
recExecute,
recExecuteBlock,
recClear,
- recShutdown
+ recShutdown,
+ recSetPGXPMode
};
#endif