diff options
| author | iCatButler <i.am.catbutler@gmail.com> | 2016-07-02 16:52:21 +0100 |
|---|---|---|
| committer | iCatButler <i.am.catbutler@gmail.com> | 2016-07-02 16:52:21 +0100 |
| commit | 03cfe9e6c22044c5b6e333b90c2b0021842fffad (patch) | |
| tree | 281c0ad4632c169313b2f7fc89bd9d9b9059e28f /libpcsxcore/ix86 | |
| parent | e634f6058957234c46667f74143b57fae9020745 (diff) | |
| download | pcsxr-03cfe9e6c22044c5b6e333b90c2b0021842fffad.tar.gz | |
Additional checks
- Change processor transfer functions to use take both source and destination values
- Add enum values to all debug functions to double check instructions are correct
- Temporarily store instruction codes in interpreter wrappers as these are sometimes changed by branching
- Change recompiler wrapper functions to store register values in global variables in case they're changed by the original function
Diffstat (limited to 'libpcsxcore/ix86')
| -rw-r--r-- | libpcsxcore/ix86/iPGXP.h | 190 |
1 files changed, 142 insertions, 48 deletions
diff --git a/libpcsxcore/ix86/iPGXP.h b/libpcsxcore/ix86/iPGXP.h index 8d9a7940..9cc1f21a 100644 --- a/libpcsxcore/ix86/iPGXP.h +++ b/libpcsxcore/ix86/iPGXP.h @@ -11,8 +11,10 @@ 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) \ @@ -23,6 +25,7 @@ static void pgxpRec##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();\ @@ -32,6 +35,7 @@ static void pgxpRec##op() { \ 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();\ @@ -46,6 +50,7 @@ static void pgxpRec##op() { \ reg3;\ reg4;\ PUSH32I(psxRegs.code); \ + PGXP_DBG_OP_E(op) \ CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, nReg)); \ resp += (4 * nReg) + 4; \ } @@ -55,69 +60,158 @@ 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(EBX, iRegs[_Rs_].k + _Imm_); \ + MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_); \ } \ else\ {\ - MOV32MtoR(EBX, (u32)&psxRegs.GPR.r[_Rs_]);\ + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);\ if (_Imm_)\ {\ - ADD32ItoR(EBX, _Imm_);\ + ADD32ItoR(EAX, _Imm_);\ }\ }\ + MOV32RtoM((u32)&gTempAddr, EAX);\ rec##op();\ - PUSH32R(EBX);\ + PUSH32M((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();\ + PUSH32M((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();\ + PUSH32M((u32)&gTempReg1);\ + PUSH32M((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();\ + PUSH32M((u32)&gTempReg1);\ + PUSH32M((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();\ +// PUSH32M((u32)&gTempReg);\ +// reg2;\ +// PUSH32I(psxRegs.code); \ +// CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 2)); \ +// resp += 12; \ +//} + // Rt = Rs op imm -PGXP_REC_FUNC_2_2(CPU, ADDI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), ) -PGXP_REC_FUNC_2_2(CPU, ADDIU, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), ) -PGXP_REC_FUNC_2_2(CPU, ANDI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), ) -PGXP_REC_FUNC_2_2(CPU, ORI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), ) -PGXP_REC_FUNC_2_2(CPU, XORI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), ) -PGXP_REC_FUNC_2_2(CPU, SLTI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), ) -PGXP_REC_FUNC_2_2(CPU, SLTIU, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), ) +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_2_2(CPU, ADD, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, ADDU, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, SUB, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, SUBU, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, AND, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, OR, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, XOR, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, NOR, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, SLT, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, SLTU, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), ) +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_2_2(CPU, MULT, 0, 4, iPushReg(_Rt_), iPushReg(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi)) -PGXP_REC_FUNC_2_2(CPU, MULTU, 0, 4, iPushReg(_Rt_), iPushReg(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi)) -PGXP_REC_FUNC_2_2(CPU, DIV, 0, 4, iPushReg(_Rt_), iPushReg(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi)) -PGXP_REC_FUNC_2_2(CPU, DIVU, 0, 4, iPushReg(_Rt_), iPushReg(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi)) +PGXP_REC_FUNC_R2_2(CPU, MULT, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi)) +PGXP_REC_FUNC_R2_2(CPU, MULTU, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi)) +PGXP_REC_FUNC_R2_2(CPU, DIV, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi)) +PGXP_REC_FUNC_R2_2(CPU, DIVU, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi)) -PGXP_REC_FUNC_2(CPU, SB, iPushOfB(), iPushReg(_Rt_)) -PGXP_REC_FUNC_2(CPU, SH, iPushOfB(), iPushReg(_Rt_)) -PGXP_REC_FUNC_2(CPU, SW, iPushOfB(), iPushReg(_Rt_)) -PGXP_REC_FUNC_2(CPU, SWL, iPushOfB(), iPushReg(_Rt_)) -PGXP_REC_FUNC_2(CPU, SWR, iPushOfB(), iPushReg(_Rt_)) +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_)) @@ -128,34 +222,34 @@ 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_2_2(CPU, SLL, !_Rd_, 2, iPushReg(_Rt_), , iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, SRL, !_Rd_, 2, iPushReg(_Rt_), , iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, SRA, !_Rd_, 2, iPushReg(_Rt_), , iPushReg(_Rd_), ) +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_2_2(CPU, SLLV, !_Rd_, 3, iPushReg(_Rs_), iPushReg(_Rt_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, SRLV, !_Rd_, 3, iPushReg(_Rs_), iPushReg(_Rt_), iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, SRAV, !_Rd_, 3, iPushReg(_Rs_), iPushReg(_Rt_), iPushReg(_Rd_), ) +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_2_2(CPU, MFHI, !_Rd_, 2, PUSH32M((u32)&psxRegs.GPR.n.hi), , iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, MTHI, 0, 2, iPushReg(_Rd_), , PUSH32M((u32)&psxRegs.GPR.n.hi), ) -PGXP_REC_FUNC_2_2(CPU, MFLO, !_Rd_, 2, PUSH32M((u32)&psxRegs.GPR.n.lo), , iPushReg(_Rd_), ) -PGXP_REC_FUNC_2_2(CPU, MTLO, 0, 2, iPushReg(_Rd_), , PUSH32M((u32)&psxRegs.GPR.n.lo), ) +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_), PUSH32M((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_), PUSH32M((u32)&psxRegs.GPR.n.lo)) // COP2 (GTE) -PGXP_REC_FUNC_2_2(GTE, MFC2, !_Rt_, 1, , , , PUSH32M((u32)&psxRegs.CP2D.r[_Rd_])) -PGXP_REC_FUNC_2_2(GTE, CFC2, !_Rt_, 1, , , , PUSH32M((u32)&psxRegs.CP2C.r[_Rd_])) -PGXP_REC_FUNC_2_2(GTE, MTC2, 0, 1, , , , iPushReg(_Rt_)) -PGXP_REC_FUNC_2_2(GTE, CTC2, 0, 1, , , , iPushReg(_Rt_)) +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_), PUSH32M((u32)&psxRegs.CP2D.r[_Rd_])) +PGXP_REC_FUNC_R1_1(GTE, CTC2, 0, CPU_REG(_Rt_), PUSH32M((u32)&psxRegs.CP2C.r[_Rd_])) PGXP_REC_FUNC_ADDR_1(GTE, LWC2, PUSH32M((u32)&psxRegs.CP2D.r[_Rt_])) PGXP_REC_FUNC_ADDR_1(GTE, SWC2, PUSH32M((u32)&psxRegs.CP2D.r[_Rt_])) // COP0 -PGXP_REC_FUNC_2_2(CP0, MFC0, !_Rd_, 1, , , , PUSH32M((u32)&psxRegs.CP0.r[_Rd_])) -PGXP_REC_FUNC_2_2(CP0, CFC0, !_Rd_, 1, , , , PUSH32M((u32)&psxRegs.CP0.r[_Rd_])) -PGXP_REC_FUNC_2_2(CP0, MTC0, !_Rt_, 1, , , , iPushReg(_Rt_)) -PGXP_REC_FUNC_2_2(CP0, CTC0, !_Rt_, 1, , , , iPushReg(_Rt_)) +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_), PUSH32M((u32)&psxRegs.CP0.r[_Rd_])) +PGXP_REC_FUNC_R1_1(CP0, CTC0, !_Rt_, CPU_REG(_Rt_), PUSH32M((u32)&psxRegs.CP0.r[_Rd_])) PGXP_REC_FUNC(CP0, RFE) #endif//_I_PGXP_H_ |
