pcsxr/libpcsxcore/ix86_64/iPGXP-64.h

256 lines
7.9 KiB
C

#ifndef _I_PGXP_H_
#define _I_PGXP_H_
/////////////////////////////////////////////
// PGXP wrapper functions
/////////////////////////////////////////////
void 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_