Added changes to MIPSInstructionFactories. Not a singleton anymore, so it allows a 32-bits and 64-bits version of the architecture to live together.

PsfPlayer bios memory ownership fixes.

git-svn-id: http://svn.purei.org/purei/trunk@490 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
jpd002 2009-03-30 04:57:52 +00:00
parent 797ddf8242
commit a6e12114d7
29 changed files with 1148 additions and 1077 deletions

View File

@ -44,8 +44,7 @@ void CBasicBlock::Compile()
m_context.m_pArch->CompileInstruction(
address,
&codeGen,
&m_context,
true);
&m_context);
//Sanity check
assert(codeGen.IsStackEmpty());
}

View File

@ -6,12 +6,6 @@
#include "offsetof_def.h"
#include "MemoryUtils.h"
CCOP_FPU g_COPFPU(MIPS_REGSIZE_64);
uint8 CCOP_FPU::m_nFT;
uint8 CCOP_FPU::m_nFS;
uint8 CCOP_FPU::m_nFD;
uint32 CCOP_FPU::m_nCCMask[8] =
{
0x00800000,
@ -25,17 +19,17 @@ uint32 CCOP_FPU::m_nCCMask[8] =
};
CCOP_FPU::CCOP_FPU(MIPS_REGSIZE nRegSize) :
CMIPSCoprocessor(nRegSize)
CMIPSCoprocessor(nRegSize),
m_nFT(0),
m_nFS(0),
m_nFD(0)
{
SetupReflectionTables();
}
void CCOP_FPU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx, bool nParent)
void CCOP_FPU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx)
{
if(nParent)
{
SetupQuickVariables(nAddress, codeGen, pCtx);
}
SetupQuickVariables(nAddress, codeGen, pCtx);
m_nFT = (uint8)((m_nOpcode >> 16) & 0x1F);
m_nFS = (uint8)((m_nOpcode >> 11) & 0x1F);
@ -45,7 +39,7 @@ void CCOP_FPU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCt
{
case 0x11:
//COP1
m_pOpGeneral[(m_nOpcode >> 21) & 0x1F]();
((this)->*(m_pOpGeneral[(m_nOpcode >> 21) & 0x1F]))();
break;
case 0x31:
LWC1();
@ -145,13 +139,13 @@ void CCOP_FPU::BC1()
//10
void CCOP_FPU::S()
{
m_pOpSingle[(m_nOpcode & 0x3F)]();
((this)->*(m_pOpSingle[(m_nOpcode & 0x3F)]))();
}
//14
void CCOP_FPU::W()
{
m_pOpWord[(m_nOpcode & 0x3F)]();
((this)->*(m_pOpWord[(m_nOpcode & 0x3F)]))();
}
//////////////////////////////////////////////////
@ -399,54 +393,54 @@ void CCOP_FPU::SWC1()
//Opcode Tables
//////////////////////////////////////////////////
void (*CCOP_FPU::m_pOpGeneral[0x20])() =
CCOP_FPU::InstructionFuncConstant CCOP_FPU::m_pOpGeneral[0x20] =
{
//0x00
MFC1, Illegal, Illegal, Illegal, MTC1, Illegal, CTC1, Illegal,
&MFC1, &Illegal, &Illegal, &Illegal, &MTC1, &Illegal, &CTC1, &Illegal,
//0x08
BC1, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&BC1, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
S, Illegal, Illegal, Illegal, W, Illegal, Illegal, Illegal,
&S, &Illegal, &Illegal, &Illegal, &W, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CCOP_FPU::m_pOpSingle[0x40])() =
CCOP_FPU::InstructionFuncConstant CCOP_FPU::m_pOpSingle[0x40] =
{
//0x00
ADD_S, SUB_S, MUL_S, DIV_S, SQRT_S, ABS_S, MOV_S, NEG_S,
&ADD_S, &SUB_S, &MUL_S, &DIV_S, &SQRT_S, &ABS_S, &MOV_S, &NEG_S,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
ADDA_S, Illegal, MULA_S, Illegal, MADD_S, MSUB_S, Illegal, Illegal,
&ADDA_S, &Illegal, &MULA_S, &Illegal, &MADD_S, &MSUB_S, &Illegal, &Illegal,
//0x20
Illegal, Illegal, Illegal, Illegal, CVT_W_S, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &CVT_W_S, &Illegal, &Illegal, &Illegal,
//0x28
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x30
Illegal, Illegal, C_EQ_S, Illegal, C_LT_S, Illegal, C_LE_S, Illegal,
&Illegal, &Illegal, &C_EQ_S, &Illegal, &C_LT_S, &Illegal, &C_LE_S, &Illegal,
//0x38
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CCOP_FPU::m_pOpWord[0x40])() =
CCOP_FPU::InstructionFuncConstant CCOP_FPU::m_pOpWord[0x40] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x20
CVT_S_W, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&CVT_S_W, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x28
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x30
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x38
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};

View File

@ -8,7 +8,7 @@ class CCOP_FPU : public CMIPSCoprocessor
{
public:
CCOP_FPU(MIPS_REGSIZE);
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*, bool);
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*);
virtual void GetInstruction(uint32, char*);
virtual void GetArguments(uint32, uint32, char*);
virtual uint32 GetEffectiveAddress(uint32, uint32);
@ -42,57 +42,59 @@ protected:
MIPSReflection::SUBTABLE m_ReflWTable;
private:
static uint8 m_nFT;
static uint8 m_nFS;
static uint8 m_nFD;
typedef void (CCOP_FPU::*InstructionFuncConstant)();
uint8 m_nFT;
uint8 m_nFS;
uint8 m_nFD;
static uint32 m_nCCMask[8];
static void SetCCBit(bool, uint32);
static void TestCCBit(uint32);
void SetCCBit(bool, uint32);
void TestCCBit(uint32);
static void (*m_pOpGeneral[0x20])();
static void (*m_pOpSingle[0x40])();
static void (*m_pOpWord[0x40])();
static InstructionFuncConstant m_pOpGeneral[0x20];
static InstructionFuncConstant m_pOpSingle[0x40];
static InstructionFuncConstant m_pOpWord[0x40];
//General
static void MFC1();
static void MTC1();
static void CTC1();
static void BC1();
static void S();
static void W();
void MFC1();
void MTC1();
void CTC1();
void BC1();
void S();
void W();
//Branch
static void BC1F();
static void BC1T();
static void BC1FL();
static void BC1TL();
void BC1F();
void BC1T();
void BC1FL();
void BC1TL();
//Single
static void ADD_S();
static void SUB_S();
static void MUL_S();
static void DIV_S();
static void SQRT_S();
static void ABS_S();
static void MOV_S();
static void NEG_S();
static void ADDA_S();
static void MULA_S();
static void MADD_S();
static void MSUB_S();
static void CVT_W_S();
static void C_EQ_S();
static void C_LT_S();
static void C_LE_S();
void ADD_S();
void SUB_S();
void MUL_S();
void DIV_S();
void SQRT_S();
void ABS_S();
void MOV_S();
void NEG_S();
void ADDA_S();
void MULA_S();
void MADD_S();
void MSUB_S();
void CVT_W_S();
void C_EQ_S();
void C_LT_S();
void C_LE_S();
//Word
static void CVT_S_W();
void CVT_S_W();
//Misc
static void LWC1();
static void SWC1();
void LWC1();
void SWC1();
//Reflection tables
static MIPSReflection::INSTRUCTION m_cReflGeneral[64];
@ -102,6 +104,4 @@ private:
static MIPSReflection::INSTRUCTION m_cReflW[64];
};
extern CCOP_FPU g_COPFPU;
#endif

View File

@ -6,9 +6,6 @@
#include "CodeGen.h"
#include "offsetof_def.h"
uint8 CCOP_SCU::m_nRT;
uint8 CCOP_SCU::m_nRD;
char* CCOP_SCU::m_sRegName[] =
{
"Index",
@ -45,25 +42,22 @@ char* CCOP_SCU::m_sRegName[] =
"*RESERVED*"
};
CCOP_SCU g_COPSCU(MIPS_REGSIZE_64);
CCOP_SCU::CCOP_SCU(MIPS_REGSIZE nRegSize) :
CMIPSCoprocessor(nRegSize)
CMIPSCoprocessor(nRegSize),
m_nRT(0),
m_nRD(0)
{
}
void CCOP_SCU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx, bool nParent)
void CCOP_SCU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx)
{
if(nParent)
{
SetupQuickVariables(nAddress, codeGen, pCtx);
}
SetupQuickVariables(nAddress, codeGen, pCtx);
m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F);
m_nRD = (uint8)((m_nOpcode >> 11) & 0x1F);
m_pOpGeneral[(m_nOpcode >> 21) & 0x1F]();
((this)->*(m_pOpGeneral[(m_nOpcode >> 21) & 0x1F]))();
}
//////////////////////////////////////////////////
@ -89,7 +83,7 @@ void CCOP_SCU::MTC0()
//10
void CCOP_SCU::CO()
{
m_pOpCO[(m_nOpcode & 0x3F)]();
((this)->*(m_pOpCO[(m_nOpcode & 0x3F)]))();
}
//////////////////////////////////////////////////
@ -158,36 +152,36 @@ void CCOP_SCU::DI()
//Opcode Tables
//////////////////////////////////////////////////
void (*CCOP_SCU::m_pOpGeneral[0x20])() =
CCOP_SCU::InstructionFuncConstant CCOP_SCU::m_pOpGeneral[0x20] =
{
//0x00
MFC0, Illegal, Illegal, Illegal, MTC0, Illegal, Illegal, Illegal,
&MFC0, &Illegal, &Illegal, &Illegal, &MTC0, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
CO, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&CO, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CCOP_SCU::m_pOpCO[0x40])() =
CCOP_SCU::InstructionFuncConstant CCOP_SCU::m_pOpCO[0x40] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
ERET, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&ERET, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x20
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x28
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x30
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x38
EI, DI, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&EI, &DI, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void CCOP_SCU::GetInstruction(uint32 nOpcode, char* sText)

View File

@ -14,7 +14,7 @@ public:
};
CCOP_SCU(MIPS_REGSIZE);
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*, bool);
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*);
virtual void GetInstruction(uint32, char*);
virtual void GetArguments(uint32, uint32, char*);
virtual uint32 GetEffectiveAddress(uint32, uint32);
@ -23,24 +23,23 @@ public:
static char* m_sRegName[];
private:
typedef void (CCOP_SCU::*InstructionFuncConstant)();
static void (*m_pOpGeneral[0x20])();
static void (*m_pOpCO[0x40])();
static InstructionFuncConstant m_pOpGeneral[0x20];
static InstructionFuncConstant m_pOpCO[0x40];
static uint8 m_nRT;
static uint8 m_nRD;
uint8 m_nRT;
uint8 m_nRD;
//General
static void MFC0();
static void MTC0();
static void CO();
void MFC0();
void MTC0();
void CO();
//CO
static void ERET();
static void EI();
static void DI();
void ERET();
void EI();
void DI();
};
extern CCOP_SCU g_COPSCU;
#endif

View File

@ -8,29 +8,22 @@
using namespace std;
CCOP_VU g_COPVU(MIPS_REGSIZE_64);
uint8 CCOP_VU::m_nFT = 0;
uint8 CCOP_VU::m_nFS = 0;
uint8 CCOP_VU::m_nFD = 0;
uint8 CCOP_VU::m_nDest = 0;
uint8 CCOP_VU::m_nFTF = 0;
uint8 CCOP_VU::m_nFSF = 0;
uint8 CCOP_VU::m_nBc = 0;
CCOP_VU::CCOP_VU(MIPS_REGSIZE nRegSize) :
CMIPSCoprocessor(nRegSize)
CMIPSCoprocessor(nRegSize),
m_nFT(0),
m_nFS(0),
m_nFD(0),
m_nDest(0),
m_nFTF(0),
m_nFSF(0),
m_nBc(0)
{
SetupReflectionTables();
}
void CCOP_VU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx, bool nParent)
void CCOP_VU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx)
{
if(nParent)
{
SetupQuickVariables(nAddress, codeGen, pCtx);
}
SetupQuickVariables(nAddress, codeGen, pCtx);
m_nDest = (uint8)((m_nOpcode >> 21) & 0x0F);
@ -47,7 +40,7 @@ void CCOP_VU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx
{
case 0x12:
//COP2
m_pOpCop2[(m_nOpcode >> 21) & 0x1F]();
((this)->*(m_pOpCop2[(m_nOpcode >> 21) & 0x1F]))();
break;
case 0x36:
//LQC2
@ -187,7 +180,7 @@ void CCOP_VU::CTC2()
//10-1F
void CCOP_VU::V()
{
m_pOpVector[(m_nOpcode & 0x3F)]();
((this)->*(m_pOpVector[(m_nOpcode & 0x3F)]))();
}
//////////////////////////////////////////////////
@ -302,25 +295,25 @@ void CCOP_VU::VMINI()
//3C
void CCOP_VU::VX0()
{
m_pOpVx0[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVx0[(m_nOpcode >> 6) & 0x1F]))();
}
//3D
void CCOP_VU::VX1()
{
m_pOpVx1[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVx1[(m_nOpcode >> 6) & 0x1F]))();
}
//3E
void CCOP_VU::VX2()
{
m_pOpVx2[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVx2[(m_nOpcode >> 6) & 0x1F]))();
}
//3F
void CCOP_VU::VX3()
{
m_pOpVx3[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVx3[(m_nOpcode >> 6) & 0x1F]))();
}
//////////////////////////////////////////////////
@ -485,82 +478,82 @@ void CCOP_VU::VRXOR()
//Opcode Tables
//////////////////////////////////////////////////
void (*CCOP_VU::m_pOpCop2[0x20])() =
CCOP_VU::InstructionFuncConstant CCOP_VU::m_pOpCop2[0x20] =
{
//0x00
Illegal, QMFC2, CFC2, Illegal, Illegal, QMTC2, CTC2, Illegal,
&Illegal, &QMFC2, &CFC2, &Illegal, &Illegal, &QMTC2, &CTC2, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
V, V, V, V, V, V, V, V,
&V, &V, &V, &V, &V, &V, &V, &V,
//0x18
V, V, V, V, V, V, V, V,
&V, &V, &V, &V, &V, &V, &V, &V,
};
void (*CCOP_VU::m_pOpVector[0x40])() =
CCOP_VU::InstructionFuncConstant CCOP_VU::m_pOpVector[0x40] =
{
//0x00
VADDbc, VADDbc, VADDbc, VADDbc, VSUBbc, VSUBbc, VSUBbc, VSUBbc,
&VADDbc, &VADDbc, &VADDbc, &VADDbc, &VSUBbc, &VSUBbc, &VSUBbc, &VSUBbc,
//0x08
VMADDbc, VMADDbc, VMADDbc, VMADDbc, VMSUBbc, VMSUBbc, VMSUBbc, VMSUBbc,
&VMADDbc, &VMADDbc, &VMADDbc, &VMADDbc, &VMSUBbc, &VMSUBbc, &VMSUBbc, &VMSUBbc,
//0x10
VMAXbc, Illegal, Illegal, Illegal, VMINIbc, Illegal, Illegal, Illegal,
&VMAXbc, &Illegal, &Illegal, &Illegal, &VMINIbc, &Illegal, &Illegal, &Illegal,
//0x18
VMULbc, VMULbc, VMULbc, VMULbc, VMULq, Illegal, Illegal, Illegal,
&VMULbc, &VMULbc, &VMULbc, &VMULbc, &VMULq, &Illegal, &Illegal, &Illegal,
//0x20
VADDq, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&VADDq, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x28
VADD, Illegal, VMUL, VMAX, VSUB, Illegal, VOPMSUB, VMINI,
&VADD, &Illegal, &VMUL, &VMAX, &VSUB, &Illegal, &VOPMSUB, &VMINI,
//0x30
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x38
Illegal, Illegal, Illegal, Illegal, VX0, VX1, VX2, VX3,
&Illegal, &Illegal, &Illegal, &Illegal, &VX0, &VX1, &VX2, &VX3,
};
void (*CCOP_VU::m_pOpVx0[0x20])() =
CCOP_VU::InstructionFuncConstant CCOP_VU::m_pOpVx0[0x20] =
{
//0x00
VADDAbc, VSUBAbc, VMADDAbc, VMSUBAbc, VITOF0, VFTOI0, VMULAbc, Illegal,
&VADDAbc, &VSUBAbc, &VMADDAbc, &VMSUBAbc, &VITOF0, &VFTOI0, &VMULAbc, &Illegal,
//0x08
Illegal, Illegal, VADDA, Illegal, VMOVE, Illegal, VDIV, Illegal,
&Illegal, &Illegal, &VADDA, &Illegal, &VMOVE, &Illegal, &VDIV, &Illegal,
//0x10
VRNEXT, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&VRNEXT, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CCOP_VU::m_pOpVx1[0x20])() =
CCOP_VU::InstructionFuncConstant CCOP_VU::m_pOpVx1[0x20] =
{
//0x00
VADDAbc, VSUBAbc, VMADDAbc, VMSUBAbc, VITOF4, VFTOI4, VMULAbc, Illegal,
&VADDAbc, &VSUBAbc, &VMADDAbc, &VMSUBAbc, &VITOF4, &VFTOI4, &VMULAbc, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, VMR32, Illegal, VSQRT, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &VMR32, &Illegal, &VSQRT, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CCOP_VU::m_pOpVx2[0x20])() =
CCOP_VU::InstructionFuncConstant CCOP_VU::m_pOpVx2[0x20] =
{
//0x00
VADDAbc, VSUBAbc, VMADDAbc, VMSUBAbc, Illegal, Illegal, VMULAbc, Illegal,
&VADDAbc, &VSUBAbc, &VMADDAbc, &VMSUBAbc, &Illegal, &Illegal, &VMULAbc, &Illegal,
//0x08
Illegal, Illegal, Illegal, VOPMULA, Illegal, Illegal, VRSQRT, Illegal,
&Illegal, &Illegal, &Illegal, &VOPMULA, &Illegal, &Illegal, &VRSQRT, &Illegal,
//0x10
VRINIT, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&VRINIT, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CCOP_VU::m_pOpVx3[0x20])() =
CCOP_VU::InstructionFuncConstant CCOP_VU::m_pOpVx3[0x20] =
{
//0x00
VADDAbc, VSUBAbc, VMADDAbc, VMSUBAbc, VITOF15, Illegal, VMULAbc, VCLIP,
&VADDAbc, &VSUBAbc, &VMADDAbc, &VMSUBAbc, &VITOF15, &Illegal, &VMULAbc, &VCLIP,
//0x08
Illegal, Illegal, Illegal, VNOP, Illegal, Illegal, VWAITQ, Illegal,
&Illegal, &Illegal, &Illegal, &VNOP, &Illegal, &Illegal, &VWAITQ, &Illegal,
//0x10
VRXOR, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&VRXOR, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};

View File

@ -9,13 +9,15 @@ class CCOP_VU : public CMIPSCoprocessor
public:
CCOP_VU(MIPS_REGSIZE);
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*, bool);
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*);
virtual void GetInstruction(uint32, char*);
virtual void GetArguments(uint32, uint32, char*);
virtual uint32 GetEffectiveAddress(uint32, uint32);
virtual bool IsBranch(uint32);
protected:
typedef void (CCOP_VU::*InstructionFuncConstant)();
void SetupReflectionTables();
static void ReflMnemI(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
@ -41,87 +43,87 @@ protected:
MIPSReflection::SUBTABLE m_ReflVX2Table;
MIPSReflection::SUBTABLE m_ReflVX3Table;
static void (*m_pOpCop2[0x20])();
static void (*m_pOpVector[0x40])();
static void (*m_pOpVx0[0x20])();
static void (*m_pOpVx1[0x20])();
static void (*m_pOpVx2[0x20])();
static void (*m_pOpVx3[0x20])();
static InstructionFuncConstant m_pOpCop2[0x20];
static InstructionFuncConstant m_pOpVector[0x40];
static InstructionFuncConstant m_pOpVx0[0x20];
static InstructionFuncConstant m_pOpVx1[0x20];
static InstructionFuncConstant m_pOpVx2[0x20];
static InstructionFuncConstant m_pOpVx3[0x20];
private:
//General
static void LQC2();
static void SQC2();
void LQC2();
void SQC2();
//COP2
static void QMFC2();
static void CFC2();
static void QMTC2();
static void CTC2();
static void V();
void QMFC2();
void CFC2();
void QMTC2();
void CTC2();
void V();
//Vector
static void VADDbc();
static void VSUBbc();
static void VMADDbc();
static void VMSUBbc();
static void VMAXbc();
static void VMINIbc();
static void VMULbc();
static void VMULq();
static void VADDq();
static void VADD();
static void VMUL();
static void VMAX();
static void VSUB();
static void VOPMSUB();
static void VMINI();
static void VX0();
static void VX1();
static void VX2();
static void VX3();
void VADDbc();
void VSUBbc();
void VMADDbc();
void VMSUBbc();
void VMAXbc();
void VMINIbc();
void VMULbc();
void VMULq();
void VADDq();
void VADD();
void VMUL();
void VMAX();
void VSUB();
void VOPMSUB();
void VMINI();
void VX0();
void VX1();
void VX2();
void VX3();
//Vx (Common)
static void VADDAbc();
static void VSUBAbc();
static void VMULAbc();
static void VMADDAbc();
static void VMSUBAbc();
void VADDAbc();
void VSUBAbc();
void VMULAbc();
void VMADDAbc();
void VMSUBAbc();
//V0
static void VITOF0();
static void VFTOI0();
static void VADDA();
static void VMOVE();
static void VDIV();
static void VRNEXT();
void VITOF0();
void VFTOI0();
void VADDA();
void VMOVE();
void VDIV();
void VRNEXT();
//V1
static void VITOF4();
static void VFTOI4();
static void VMR32();
static void VSQRT();
void VITOF4();
void VFTOI4();
void VMR32();
void VSQRT();
//V2
static void VOPMULA();
static void VRSQRT();
static void VRINIT();
void VOPMULA();
void VRSQRT();
void VRINIT();
//V3
static void VITOF15();
static void VCLIP();
static void VNOP();
static void VWAITQ();
static void VRXOR();
void VITOF15();
void VCLIP();
void VNOP();
void VWAITQ();
void VRXOR();
static uint8 m_nBc;
static uint8 m_nDest;
static uint8 m_nFSF;
static uint8 m_nFTF;
uint8 m_nBc;
uint8 m_nDest;
uint8 m_nFSF;
uint8 m_nFTF;
static uint8 m_nFS;
static uint8 m_nFT;
static uint8 m_nFD;
uint8 m_nFS;
uint8 m_nFT;
uint8 m_nFD;
//Reflection tables
static MIPSReflection::INSTRUCTION m_cReflGeneral[64];
@ -134,6 +136,4 @@ private:
};
extern CCOP_VU g_COPVU;
#endif

View File

@ -714,16 +714,23 @@ void CCodeGen::Add()
{
CommutativeRelativeConstant::PatternValue ops(GetPattern<CommutativeRelativeConstant>());
unsigned int registerId = AllocateRegister();
if(ops.second == 0)
{
PushRel(ops.first);
}
else
{
unsigned int registerId = AllocateRegister();
LoadRelativeInRegister(registerId, ops.first);
LoadRelativeInRegister(registerId, ops.first);
//add reg, Immediate
m_Assembler.AddId(
CX86Assembler::MakeRegisterAddress(m_nRegisterLookupEx[registerId]),
ops.second);
//add reg, Immediate
m_Assembler.AddId(
CX86Assembler::MakeRegisterAddress(m_nRegisterLookupEx[registerId]),
ops.second);
PushReg(registerId);
PushReg(registerId);
}
}
else if(FitsPattern<RelativeRelative>())
{
@ -1190,6 +1197,14 @@ void CCodeGen::Cmp(CONDITION nCondition)
//setgt res[l]
m_Assembler.SetgEb(CX86Assembler::MakeByteRegisterAddress(m_nRegisterLookupEx[resultRegister]));
break;
case CONDITION_LT:
//setl res[l]
m_Assembler.SetlEb(CX86Assembler::MakeByteRegisterAddress(m_nRegisterLookupEx[resultRegister]));
break;
case CONDITION_LE:
//setle res[l]
m_Assembler.SetleEb(CX86Assembler::MakeByteRegisterAddress(m_nRegisterLookupEx[resultRegister]));
break;
default:
throw exception();
break;
@ -1218,6 +1233,20 @@ void CCodeGen::Cmp(CONDITION nCondition)
Cmp(nCondition);
}
else if(FitsPattern<RelativeConstant>())
{
RelativeConstant::PatternValue ops = GetPattern<RelativeConstant>();
unsigned int register1 = AllocateRegister();
unsigned int register2 = AllocateRegister();
LoadRelativeInRegister(register1, ops.first);
LoadConstantInRegister(register2, ops.second);
PushReg(register1);
PushReg(register2);
Cmp(nCondition);
}
else if(FitsPattern<RegisterConstant>())
{
RegisterConstant::PatternValue ops = GetPattern<RegisterConstant>();

View File

@ -9,38 +9,36 @@
using namespace std;
using namespace std::tr1;
CMA_EE g_MAEE;
CMA_EE::CMA_EE() :
CMA_MIPSIV(MIPS_REGSIZE_64)
{
m_pOpGeneral[0x1E] = LQ;
m_pOpGeneral[0x1F] = SQ;
m_pOpGeneral[0x1E] = bind(&CMA_EE::LQ, this);
m_pOpGeneral[0x1F] = bind(&CMA_EE::SQ, this);
//OS special instructions
m_pOpSpecial[0x1D] = REEXCPT;
m_pOpSpecial[0x1D] = bind(&CMA_EE::REEXCPT, this);
m_pOpRegImm[0x18] = MTSAB;
m_pOpRegImm[0x19] = MTSAH;
m_pOpRegImm[0x18] = bind(&CMA_EE::MTSAB, this);
m_pOpRegImm[0x19] = bind(&CMA_EE::MTSAH, this);
m_pOpSpecial2[0x00] = MADD;
m_pOpSpecial2[0x04] = PLZCW;
m_pOpSpecial2[0x08] = MMI0;
m_pOpSpecial2[0x09] = MMI2;
m_pOpSpecial2[0x10] = MFHI1;
m_pOpSpecial2[0x11] = MTHI1;
m_pOpSpecial2[0x12] = MFLO1;
m_pOpSpecial2[0x13] = MTLO1;
m_pOpSpecial2[0x18] = MULT1;
m_pOpSpecial2[0x19] = MULTU1;
m_pOpSpecial2[0x1A] = DIV1;
m_pOpSpecial2[0x1B] = DIVU1;
m_pOpSpecial2[0x28] = MMI1;
m_pOpSpecial2[0x29] = MMI3;
m_pOpSpecial2[0x34] = PSLLH;
m_pOpSpecial2[0x36] = PSRLH;
m_pOpSpecial2[0x37] = PSRAH;
m_pOpSpecial2[0x3F] = PSRAW;
m_pOpSpecial2[0x00] = bind(&CMA_EE::MADD, this);
m_pOpSpecial2[0x04] = bind(&CMA_EE::PLZCW, this);
m_pOpSpecial2[0x08] = bind(&CMA_EE::MMI0, this);
m_pOpSpecial2[0x09] = bind(&CMA_EE::MMI2, this);
m_pOpSpecial2[0x10] = bind(&CMA_EE::MFHI1, this);
m_pOpSpecial2[0x11] = bind(&CMA_EE::MTHI1, this);
m_pOpSpecial2[0x12] = bind(&CMA_EE::MFLO1, this);
m_pOpSpecial2[0x13] = bind(&CMA_EE::MTLO1, this);
m_pOpSpecial2[0x18] = bind(&CMA_EE::MULT1, this);
m_pOpSpecial2[0x19] = bind(&CMA_EE::MULTU1, this);
m_pOpSpecial2[0x1A] = bind(&CMA_EE::DIV1, this);
m_pOpSpecial2[0x1B] = bind(&CMA_EE::DIVU1, this);
m_pOpSpecial2[0x28] = bind(&CMA_EE::MMI1, this);
m_pOpSpecial2[0x29] = bind(&CMA_EE::MMI3, this);
m_pOpSpecial2[0x34] = bind(&CMA_EE::PSLLH, this);
m_pOpSpecial2[0x36] = bind(&CMA_EE::PSRLH, this);
m_pOpSpecial2[0x37] = bind(&CMA_EE::PSRAH, this);
m_pOpSpecial2[0x3F] = bind(&CMA_EE::PSRAW, this);
SetupReflectionTables();
}
@ -222,13 +220,13 @@ void CMA_EE::PLZCW()
//08
void CMA_EE::MMI0()
{
m_pOpMmi0[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpMmi0[(m_nOpcode >> 6) & 0x1F]))();
}
//09
void CMA_EE::MMI2()
{
m_pOpMmi2[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpMmi2[(m_nOpcode >> 6) & 0x1F]))();
}
//10
@ -274,37 +272,37 @@ void CMA_EE::MTLO1()
//18
void CMA_EE::MULT1()
{
Template_Mult32()(bind(&CCodeGen::MultS, m_codeGen), 1);
Template_Mult32(bind(&CCodeGen::MultS, m_codeGen), 1);
}
//19
void CMA_EE::MULTU1()
{
Template_Mult32()(bind(&CCodeGen::Mult, m_codeGen), 1);
Template_Mult32(bind(&CCodeGen::Mult, m_codeGen), 1);
}
//1A
void CMA_EE::DIV1()
{
Template_Div32()(bind(&CCodeGen::DivS, m_codeGen), 1);
Template_Div32(bind(&CCodeGen::DivS, m_codeGen), 1);
}
//1B
void CMA_EE::DIVU1()
{
Template_Div32()(bind(&CCodeGen::Div, m_codeGen), 1);
Template_Div32(bind(&CCodeGen::Div, m_codeGen), 1);
}
//28
void CMA_EE::MMI1()
{
m_pOpMmi1[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpMmi1[(m_nOpcode >> 6) & 0x1F]))();
}
//29
void CMA_EE::MMI3()
{
m_pOpMmi3[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpMmi3[(m_nOpcode >> 6) & 0x1F]))();
}
//34
@ -656,50 +654,50 @@ void CMA_EE::PCPYH()
//Opcode Tables
//////////////////////////////////////////////////
void (*CMA_EE::m_pOpMmi0[0x20])() =
CMA_EE::InstructionFuncConstant CMA_EE::m_pOpMmi0[0x20] =
{
//0x00
Illegal, PSUBW, Illegal, Illegal, PADDH, Illegal, PCGTH, PMAXH,
&Illegal, &PSUBW, &Illegal, &Illegal, &PADDH, &Illegal, &PCGTH, &PMAXH,
//0x08
Illegal, PSUBB, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &PSUBB, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
PADDSW, Illegal, PEXTLW, Illegal, Illegal, Illegal, PEXTLH, PPACH,
&PADDSW, &Illegal, &PEXTLW, &Illegal, &Illegal, &Illegal, &PEXTLH, &PPACH,
//0x18
Illegal, Illegal, PEXTLB, PPACB, Illegal, Illegal, PEXT5, Illegal,
&Illegal, &Illegal, &PEXTLB, &PPACB, &Illegal, &Illegal, &PEXT5, &Illegal,
};
void (*CMA_EE::m_pOpMmi1[0x20])() =
CMA_EE::InstructionFuncConstant CMA_EE::m_pOpMmi1[0x20] =
{
//0x00
Illegal, Illegal, PCEQW, Illegal, Illegal, Illegal, Illegal, PMINH,
&Illegal, &Illegal, &PCEQW, &Illegal, &Illegal, &Illegal, &Illegal, &PMINH,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
PADDUW, Illegal, PEXTUW, Illegal, Illegal, Illegal, Illegal, Illegal,
&PADDUW, &Illegal, &PEXTUW, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, PEXTUB, QFSRV, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &PEXTUB, &QFSRV, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CMA_EE::m_pOpMmi2[0x20])() =
CMA_EE::InstructionFuncConstant CMA_EE::m_pOpMmi2[0x20] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, PCPYLD, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &PCPYLD, &Illegal,
//0x10
Illegal, Illegal, PAND, PXOR, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &PAND, &PXOR, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, PROT3W,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &PROT3W,
};
void (*CMA_EE::m_pOpMmi3[0x20])() =
CMA_EE::InstructionFuncConstant CMA_EE::m_pOpMmi3[0x20] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, PCPYUD, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &PCPYUD, &Illegal,
//0x10
Illegal, Illegal, POR, PNOR, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &POR, &PNOR, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, PCPYH, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &PCPYH, &Illegal, &Illegal, &Illegal, &Illegal,
};

View File

@ -7,15 +7,17 @@ class CMA_EE : public CMA_MIPSIV
{
public:
CMA_EE();
~CMA_EE();
virtual ~CMA_EE();
protected:
typedef void (CMA_EE::*InstructionFuncConstant)();
void SetupReflectionTables();
static void (*m_pOpMmi0[0x20])();
static void (*m_pOpMmi1[0x20])();
static void (*m_pOpMmi2[0x20])();
static void (*m_pOpMmi3[0x20])();
static InstructionFuncConstant m_pOpMmi0[0x20];
static InstructionFuncConstant m_pOpMmi1[0x20];
static InstructionFuncConstant m_pOpMmi2[0x20];
static InstructionFuncConstant m_pOpMmi3[0x20];
static void ReflOpRdRt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
static void ReflOpRsImm(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
@ -34,73 +36,73 @@ protected:
private:
static void PushVector(unsigned int);
static void PullVector(unsigned int);
void PushVector(unsigned int);
void PullVector(unsigned int);
//General
static void LQ();
static void SQ();
void LQ();
void SQ();
//Special
static void REEXCPT();
void REEXCPT();
//RegImm
static void MTSAB();
static void MTSAH();
void MTSAB();
void MTSAH();
//Special2
static void MADD();
static void PLZCW();
static void MMI0();
static void MMI2();
static void MFHI1();
static void MTHI1();
static void MFLO1();
static void MTLO1();
static void MULT1();
static void MULTU1();
static void DIV1();
static void DIVU1();
static void MMI1();
static void MMI3();
static void PSLLH();
static void PSRLH();
static void PSRAH();
static void PSRAW();
void MADD();
void PLZCW();
void MMI0();
void MMI2();
void MFHI1();
void MTHI1();
void MFLO1();
void MTLO1();
void MULT1();
void MULTU1();
void DIV1();
void DIVU1();
void MMI1();
void MMI3();
void PSLLH();
void PSRLH();
void PSRAH();
void PSRAW();
//Mmi0
static void PSUBW();
static void PADDH();
static void PCGTH();
static void PMAXH();
static void PSUBB();
static void PADDSW();
static void PEXTLW();
static void PEXTLH();
static void PPACH();
static void PEXTLB();
static void PPACB();
static void PEXT5();
void PSUBW();
void PADDH();
void PCGTH();
void PMAXH();
void PSUBB();
void PADDSW();
void PEXTLW();
void PEXTLH();
void PPACH();
void PEXTLB();
void PPACB();
void PEXT5();
//Mmi1
static void PCEQW();
static void PMINH();
static void PADDUW();
static void PEXTUW();
static void PEXTUB();
static void QFSRV();
void PCEQW();
void PMINH();
void PADDUW();
void PEXTUW();
void PEXTUB();
void QFSRV();
//Mmi2
static void PCPYLD();
static void PAND();
static void PXOR();
static void PROT3W();
void PCPYLD();
void PAND();
void PXOR();
void PROT3W();
//Mmi3
static void PCPYUD();
static void POR();
static void PNOR();
static void PCPYH();
void PCPYUD();
void POR();
void PNOR();
void PCPYH();
//Reflection tables
static MIPSReflection::INSTRUCTION m_cReflMmi[64];
@ -110,6 +112,4 @@ private:
static MIPSReflection::INSTRUCTION m_cReflMmi3[32];
};
extern CMA_EE g_MAEE;
#endif

View File

@ -10,14 +10,6 @@
using namespace std::tr1;
CMA_MIPSIV g_MAMIPSIV(MIPS_REGSIZE_64);
uint8 CMA_MIPSIV::m_nRS;
uint8 CMA_MIPSIV::m_nRT;
uint8 CMA_MIPSIV::m_nRD;
uint8 CMA_MIPSIV::m_nSA;
uint16 CMA_MIPSIV::m_nImmediate;
uint32 g_LWMaskRight[4] =
{
0x00FFFFFF,
@ -169,16 +161,42 @@ void SDR_Proxy(uint32 address, uint32 rt, CMIPS* context)
CMA_MIPSIV::CMA_MIPSIV(MIPS_REGSIZE nRegSize) :
CMIPSArchitecture(nRegSize)
{
SetupInstructionTables();
SetupReflectionTables();
}
void CMA_MIPSIV::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx, bool nParent)
CMA_MIPSIV::~CMA_MIPSIV()
{
if(nParent)
}
void CMA_MIPSIV::SetupInstructionTables()
{
for(unsigned int i = 0; i < MAX_GENERAL_OPS; i++)
{
SetupQuickVariables(nAddress, codeGen, pCtx);
m_pOpGeneral[i] = bind(m_cOpGeneral[i], this);
}
for(unsigned int i = 0; i < MAX_SPECIAL_OPS; i++)
{
m_pOpSpecial[i] = bind(m_cOpSpecial[i], this);
}
for(unsigned int i = 0; i < MAX_SPECIAL2_OPS; i++)
{
m_pOpSpecial2[i] = bind(&CMA_MIPSIV::Illegal, this);
}
for(unsigned int i = 0; i < MAX_REGIMM_OPS; i++)
{
m_pOpRegImm[i] = bind(m_cOpRegImm[i], this);
}
}
void CMA_MIPSIV::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx)
{
SetupQuickVariables(nAddress, codeGen, pCtx);
m_nRS = (uint8)((m_nOpcode >> 21) & 0x1F);
m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F);
m_nRD = (uint8)((m_nOpcode >> 11) & 0x1F);
@ -234,43 +252,27 @@ void CMA_MIPSIV::JAL()
//04
void CMA_MIPSIV::BEQ()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
m_codeGen->Cmp64(CCodeGen::CONDITION_EQ);
Branch(true);
Template_BranchEq(true, false);
}
//05
void CMA_MIPSIV::BNE()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
m_codeGen->Cmp64(CCodeGen::CONDITION_EQ);
Branch(false);
Template_BranchEq(false, false);
}
//06
void CMA_MIPSIV::BLEZ()
{
//Less/Equal & Not Likely
Template_BranchLez()(true, false);
Template_BranchLez(true, false);
}
//07
void CMA_MIPSIV::BGTZ()
{
//Not Less/Equal & Not Likely
Template_BranchLez()(false, false);
Template_BranchLez(false, false);
}
//08
@ -301,8 +303,11 @@ void CMA_MIPSIV::ADDIU()
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushCst(static_cast<int16>(m_nImmediate));
m_codeGen->Add();
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
if(m_regSize == MIPS_REGSIZE_64)
{
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
}
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
}
}
@ -310,37 +315,13 @@ void CMA_MIPSIV::ADDIU()
//0A
void CMA_MIPSIV::SLTI()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushCst(static_cast<int16>(m_nImmediate));
m_codeGen->PushCst(m_nImmediate & 0x8000 ? 0xFFFFFFFF : 0x00000000);
m_codeGen->Cmp64(CCodeGen::CONDITION_LT);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
//Clear higher 32-bits
m_codeGen->PushCst(0);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
Template_SetLessThanImm(true);
}
//0B
void CMA_MIPSIV::SLTIU()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushCst(static_cast<int16>(m_nImmediate));
m_codeGen->PushCst(m_nImmediate & 0x8000 ? 0xFFFFFFFF : 0x00000000);
m_codeGen->Cmp64(CCodeGen::CONDITION_BL);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
//Clear higher 32-bits
m_codeGen->PushCst(0);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
Template_SetLessThanImm(false);
}
//0C
@ -391,8 +372,11 @@ void CMA_MIPSIV::XORI()
void CMA_MIPSIV::LUI()
{
m_codeGen->PushCst(m_nImmediate << 16);
m_codeGen->PushCst((m_nImmediate & 0x8000) ? 0xFFFFFFFF : 0x00000000);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
if(m_regSize == MIPS_REGSIZE_64)
{
m_codeGen->PushCst((m_nImmediate & 0x8000) ? 0xFFFFFFFF : 0x00000000);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
}
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
}
@ -401,7 +385,7 @@ void CMA_MIPSIV::COP0()
{
if(m_pCtx->m_pCOP[0] != NULL)
{
m_pCtx->m_pCOP[0]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, false);
m_pCtx->m_pCOP[0]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx);
}
else
{
@ -414,7 +398,7 @@ void CMA_MIPSIV::COP1()
{
if(m_pCtx->m_pCOP[1] != NULL)
{
m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, false);
m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx);
}
else
{
@ -427,7 +411,7 @@ void CMA_MIPSIV::COP2()
{
if(m_pCtx->m_pCOP[2] != NULL)
{
m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, false);
m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx);
}
else
{
@ -438,43 +422,27 @@ void CMA_MIPSIV::COP2()
//14
void CMA_MIPSIV::BEQL()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
m_codeGen->Cmp64(CCodeGen::CONDITION_EQ);
BranchLikely(true);
Template_BranchEq(true, true);
}
//15
void CMA_MIPSIV::BNEL()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
m_codeGen->Cmp64(CCodeGen::CONDITION_EQ);
BranchLikely(false);
Template_BranchEq(false, true);
}
//16
void CMA_MIPSIV::BLEZL()
{
//Less/Equal & Likely
Template_BranchLez()(true, true);
Template_BranchLez(true, true);
}
//17
void CMA_MIPSIV::BGTZL()
{
//Not Less/Equal & Likely
Template_BranchLez()(false, true);
Template_BranchLez(false, true);
}
//19
@ -556,19 +524,19 @@ void CMA_MIPSIV::LWL()
//23
void CMA_MIPSIV::LW()
{
Template_LoadUnsigned32()(reinterpret_cast<void*>(&CMemoryUtils::GetWordProxy));
Template_LoadUnsigned32(reinterpret_cast<void*>(&CMemoryUtils::GetWordProxy));
}
//24
void CMA_MIPSIV::LBU()
{
Template_LoadUnsigned32()(reinterpret_cast<void*>(&CMemoryUtils::GetByteProxy));
Template_LoadUnsigned32(reinterpret_cast<void*>(&CMemoryUtils::GetByteProxy));
}
//25
void CMA_MIPSIV::LHU()
{
Template_LoadUnsigned32()(reinterpret_cast<void*>(&CMemoryUtils::GetHalfProxy));
Template_LoadUnsigned32(reinterpret_cast<void*>(&CMemoryUtils::GetHalfProxy));
}
//26
@ -682,7 +650,7 @@ void CMA_MIPSIV::LWC1()
{
if(m_pCtx->m_pCOP[1] != NULL)
{
m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, false);
m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx);
}
else
{
@ -695,7 +663,7 @@ void CMA_MIPSIV::LDC2()
{
if(m_pCtx->m_pCOP[2] != NULL)
{
m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, false);
m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx);
}
else
{
@ -731,7 +699,7 @@ void CMA_MIPSIV::SWC1()
{
if(m_pCtx->m_pCOP[1] != NULL)
{
m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, false);
m_pCtx->m_pCOP[1]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx);
}
else
{
@ -744,7 +712,7 @@ void CMA_MIPSIV::SDC2()
{
if(m_pCtx->m_pCOP[2] != NULL)
{
m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx, false);
m_pCtx->m_pCOP[2]->CompileInstruction(m_nAddress, m_codeGen, m_pCtx);
}
else
{
@ -781,37 +749,37 @@ void CMA_MIPSIV::SD()
//00
void CMA_MIPSIV::SLL()
{
Template_ShiftCst32()(bind(&CCodeGen::Shl, m_codeGen, PLACEHOLDER_1));
Template_ShiftCst32(bind(&CCodeGen::Shl, m_codeGen, PLACEHOLDER_1));
}
//02
void CMA_MIPSIV::SRL()
{
Template_ShiftCst32()(bind(&CCodeGen::Srl, m_codeGen, PLACEHOLDER_1));
Template_ShiftCst32(bind(&CCodeGen::Srl, m_codeGen, PLACEHOLDER_1));
}
//03
void CMA_MIPSIV::SRA()
{
Template_ShiftCst32()(bind(&CCodeGen::Sra, m_codeGen, PLACEHOLDER_1));
Template_ShiftCst32(bind(&CCodeGen::Sra, m_codeGen, PLACEHOLDER_1));
}
//04
void CMA_MIPSIV::SLLV()
{
Template_ShiftVar32()(bind(&CCodeGen::Shl, m_codeGen));
Template_ShiftVar32(bind(&CCodeGen::Shl, m_codeGen));
}
//06
void CMA_MIPSIV::SRLV()
{
Template_ShiftVar32()(bind(&CCodeGen::Srl, m_codeGen));
Template_ShiftVar32(bind(&CCodeGen::Srl, m_codeGen));
}
//07
void CMA_MIPSIV::SRAV()
{
Template_ShiftVar32()(bind(&CCodeGen::Sra, m_codeGen));
Template_ShiftVar32(bind(&CCodeGen::Sra, m_codeGen));
}
//08
@ -839,13 +807,13 @@ void CMA_MIPSIV::JALR()
//0A
void CMA_MIPSIV::MOVZ()
{
Template_MovEqual()(true);
Template_MovEqual(true);
}
//0B
void CMA_MIPSIV::MOVN()
{
Template_MovEqual()(false);
Template_MovEqual(false);
}
//0C
@ -941,77 +909,49 @@ void CMA_MIPSIV::DSRLV()
//18
void CMA_MIPSIV::MULT()
{
Template_Mult32()(bind(&CCodeGen::MultS, m_codeGen), 0);
Template_Mult32(bind(&CCodeGen::MultS, m_codeGen), 0);
}
//19
void CMA_MIPSIV::MULTU()
{
Template_Mult32()(bind(&CCodeGen::Mult, m_codeGen), 0);
Template_Mult32(bind(&CCodeGen::Mult, m_codeGen), 0);
}
//1A
void CMA_MIPSIV::DIV()
{
Template_Div32()(bind(&CCodeGen::DivS, m_codeGen), 0);
Template_Div32(bind(&CCodeGen::DivS, m_codeGen), 0);
}
//1B
void CMA_MIPSIV::DIVU()
{
Template_Div32()(bind(&CCodeGen::Div, m_codeGen), 0);
Template_Div32(bind(&CCodeGen::Div, m_codeGen), 0);
}
//20
void CMA_MIPSIV::ADD()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->Add();
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
Template_Add32(true);
}
//21
void CMA_MIPSIV::ADDU()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->Add();
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
Template_Add32(false);
}
//22
void CMA_MIPSIV::SUB()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->Sub();
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
Template_Sub32(true);
}
//23
void CMA_MIPSIV::SUBU()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->Sub();
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
Template_Sub32(false);
}
//24
@ -1076,37 +1016,13 @@ void CMA_MIPSIV::NOR()
//2A
void CMA_MIPSIV::SLT()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
m_codeGen->Cmp64(CCodeGen::CONDITION_LT);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
//Clear higher 32-bits
m_codeGen->PushCst(0);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
Template_SetLessThanReg(true);
}
//2B
void CMA_MIPSIV::SLTU()
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
m_codeGen->Cmp64(CCodeGen::CONDITION_BL);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
//Clear higher 32-bits
m_codeGen->PushCst(0);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
Template_SetLessThanReg(false);
}
//2D
@ -1223,102 +1139,82 @@ void CMA_MIPSIV::DSRA32()
void CMA_MIPSIV::BLTZ()
{
//Not greater/equal & not likely
Template_BranchGez()(false, false);
Template_BranchGez(false, false);
}
//01
void CMA_MIPSIV::BGEZ()
{
//Greater/equal & not likely
Template_BranchGez()(true, false);
Template_BranchGez(true, false);
}
//02
void CMA_MIPSIV::BLTZL()
{
//Not greater/equal & likely
Template_BranchGez()(false, true);
Template_BranchGez(false, true);
}
//03
void CMA_MIPSIV::BGEZL()
{
//Greater/equal & likely
Template_BranchGez()(true, true);
Template_BranchGez(true, true);
}
//////////////////////////////////////////////////
//Opcode Tables
//////////////////////////////////////////////////
void (*CMA_MIPSIV::m_pOpGeneral[0x40])() =
CMA_MIPSIV::InstructionFuncConstant CMA_MIPSIV::m_cOpGeneral[MAX_GENERAL_OPS] =
{
//0x00
SPECIAL, REGIMM, J, JAL, BEQ, BNE, BLEZ, BGTZ,
&SPECIAL, &REGIMM, &J, &JAL, &BEQ, &BNE, &BLEZ, &BGTZ,
//0x08
ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI,
&ADDI, &ADDIU, &SLTI, &SLTIU, &ANDI, &ORI, &XORI, &LUI,
//0x10
COP0, COP1, COP2, Illegal, BEQL, BNEL, BLEZL, BGTZL,
&COP0, &COP1, &COP2, &Illegal, &BEQL, &BNEL, &BLEZL, &BGTZL,
//0x18
Illegal, DADDIU, LDL, LDR, SPECIAL2, Illegal, Illegal, Illegal,
&Illegal, &DADDIU, &LDL, &LDR, &SPECIAL2, &Illegal, &Illegal, &Illegal,
//0x20
LB, LH, LWL, LW, LBU, LHU, LWR, LWU,
&LB, &LH, &LWL, &LW, &LBU, &LHU, &LWR, &LWU,
//0x28
SB, SH, SWL, SW, SDL, SDR, SWR, CACHE,
&SB, &SH, &SWL, &SW, &SDL, &SDR, &SWR, &CACHE,
//0x30
Illegal, LWC1, Illegal, Illegal, Illegal, Illegal, LDC2, LD,
&Illegal, &LWC1, &Illegal, &Illegal, &Illegal, &Illegal, &LDC2, &LD,
//0x38
Illegal, SWC1, Illegal, Illegal, Illegal, Illegal, SDC2, SD,
&Illegal, &SWC1, &Illegal, &Illegal, &Illegal, &Illegal, &SDC2, &SD,
};
void (*CMA_MIPSIV::m_pOpSpecial[0x40])() =
CMA_MIPSIV::InstructionFuncConstant CMA_MIPSIV::m_cOpSpecial[MAX_SPECIAL_OPS] =
{
//0x00
SLL, Illegal, SRL, SRA, SLLV, Illegal, SRLV, SRAV,
&SLL, &Illegal, &SRL, &SRA, &SLLV, &Illegal, &SRLV, &SRAV,
//0x08
JR, JALR, MOVZ, MOVN, SYSCALL, BREAK, Illegal, SYNC,
&JR, &JALR, &MOVZ, &MOVN, &SYSCALL, &BREAK, &Illegal, &SYNC,
//0x10
MFHI, MTHI, MFLO, MTLO, DSLLV, Illegal, DSRLV, Illegal,
&MFHI, &MTHI, &MFLO, &MTLO, &DSLLV, &Illegal, &DSRLV, &Illegal,
//0x18
MULT, MULTU, DIV, DIVU, Illegal, Illegal, Illegal, Illegal,
&MULT, &MULTU, &DIV, &DIVU, &Illegal, &Illegal, &Illegal, &Illegal,
//0x20
ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR,
&ADD, &ADDU, &SUB, &SUBU, &AND, &OR, &XOR, &NOR,
//0x28
Illegal, Illegal, SLT, SLTU, Illegal, DADDU, Illegal, DSUBU,
&Illegal, &Illegal, &SLT, &SLTU, &Illegal, &DADDU, &Illegal, &DSUBU,
//0x30
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x38
DSLL, Illegal, DSRL, DSRA, DSLL32, Illegal, DSRL32, DSRA32,
&DSLL, &Illegal, &DSRL, &DSRA, &DSLL32, &Illegal, &DSRL32, &DSRA32,
};
void (*CMA_MIPSIV::m_pOpSpecial2[0x40])() =
CMA_MIPSIV::InstructionFuncConstant CMA_MIPSIV::m_cOpRegImm[MAX_REGIMM_OPS] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&BLTZ, &BGEZ, &BLTZL, &BGEZL, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
//0x20
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
//0x28
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
//0x30
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
//0x38
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
};
void (*CMA_MIPSIV::m_pOpRegImm[0x20])() =
{
//0x00
BLTZ, BGEZ, BLTZL, BGEZL, Illegal, Illegal, Illegal, Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};

View File

@ -9,19 +9,28 @@ class CMA_MIPSIV : public CMIPSArchitecture
{
public:
CMA_MIPSIV(MIPS_REGSIZE);
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*, bool);
virtual ~CMA_MIPSIV();
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*);
virtual void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
virtual void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
virtual bool IsInstructionBranch(CMIPS*, uint32, uint32);
virtual uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32);
protected:
void SetupReflectionTables();
enum
{
MAX_GENERAL_OPS = 0x40,
MAX_SPECIAL_OPS = 0x40,
MAX_SPECIAL2_OPS = 0x40,
MAX_REGIMM_OPS = 0x20,
};
static void (*m_pOpGeneral[0x40])();
static void (*m_pOpSpecial[0x40])();
static void (*m_pOpSpecial2[0x40])();
static void (*m_pOpRegImm[0x20])();
typedef std::tr1::function<void ()> InstructionFunction;
InstructionFunction m_pOpGeneral[MAX_GENERAL_OPS];
InstructionFunction m_pOpSpecial[MAX_SPECIAL_OPS];
InstructionFunction m_pOpSpecial2[MAX_SPECIAL2_OPS];
InstructionFunction m_pOpRegImm[MAX_REGIMM_OPS];
static void ReflOpTarget(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
static void ReflOpRtRsImm(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
@ -46,177 +55,157 @@ protected:
static bool ReflCOPIsBranch(MIPSReflection::INSTRUCTION*, CMIPS*, uint32);
static uint32 ReflCOPEffeAddr(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
MIPSReflection::INSTRUCTION m_ReflGeneral[64];
MIPSReflection::INSTRUCTION m_ReflSpecial[64];
MIPSReflection::INSTRUCTION m_ReflRegImm[32];
MIPSReflection::INSTRUCTION m_ReflGeneral[MAX_GENERAL_OPS];
MIPSReflection::INSTRUCTION m_ReflSpecial[MAX_SPECIAL_OPS];
MIPSReflection::INSTRUCTION m_ReflRegImm[MAX_REGIMM_OPS];
MIPSReflection::SUBTABLE m_ReflGeneralTable;
MIPSReflection::SUBTABLE m_ReflSpecialTable;
MIPSReflection::SUBTABLE m_ReflRegImmTable;
static uint8 m_nRS;
static uint8 m_nRT;
static uint8 m_nRD;
static uint8 m_nSA;
static uint16 m_nImmediate;
uint8 m_nRS;
uint8 m_nRT;
uint8 m_nRD;
uint8 m_nSA;
uint16 m_nImmediate;
protected:
//Instruction compiler templates
typedef std::tr1::function<void (uint8)> TemplateParamedOperationFunctionType;
typedef std::tr1::function<void ()> TemplateOperationFunctionType;
struct Template_LoadUnsigned32
{
void operator()(void*);
};
struct Template_ShiftCst32
{
typedef std::tr1::function<void (uint8)> OperationFunctionType;
void operator()(const OperationFunctionType&) const;
};
struct Template_ShiftVar32
{
typedef std::tr1::function<void ()> OperationFunctionType;
void operator()(const OperationFunctionType&) const;
};
struct Template_Mult32
{
typedef std::tr1::function<void ()> OperationFunctionType;
void operator()(const OperationFunctionType&, unsigned int) const;
};
struct Template_Div32
{
typedef std::tr1::function<void ()> OperationFunctionType;
void operator()(const OperationFunctionType&, unsigned int) const;
};
struct Template_MovEqual
{
void operator()(bool) const;
};
struct Template_BranchGez
{
void operator()(bool, bool) const;
};
struct Template_BranchLez
{
void operator()(bool, bool) const;
};
void Template_Add32(bool);
void Template_Sub32(bool);
void Template_LoadUnsigned32(void*);
void Template_ShiftCst32(const TemplateParamedOperationFunctionType&);
void Template_ShiftVar32(const TemplateOperationFunctionType&);
void Template_Mult32(const TemplateOperationFunctionType&, unsigned int);
void Template_Div32(const TemplateOperationFunctionType&, unsigned int);
void Template_MovEqual(bool);
void Template_SetLessThanImm(bool);
void Template_SetLessThanReg(bool);
void Template_BranchEq(bool, bool);
void Template_BranchGez(bool, bool);
void Template_BranchLez(bool, bool);
private:
static void SPECIAL();
static void SPECIAL2();
static void REGIMM();
void SetupInstructionTables();
void SetupReflectionTables();
void SPECIAL();
void SPECIAL2();
void REGIMM();
//General
static void J();
static void JAL();
static void BEQ();
static void BNE();
static void BLEZ();
static void BGTZ();
static void ADDI();
static void ADDIU();
static void SLTI();
static void SLTIU();
static void ANDI();
static void ORI();
static void XORI();
static void LUI();
static void COP0();
static void COP1();
static void COP2();
static void BEQL();
static void BNEL();
static void BLEZL();
static void BGTZL();
static void DADDIU();
static void LDL();
static void LDR();
static void LB();
static void LH();
static void LWL();
static void LW();
static void LBU();
static void LHU();
static void LWR();
static void LWU();
static void SB();
static void SH();
static void SWL();
static void SW();
static void SDL();
static void SDR();
static void SWR();
static void CACHE();
static void LWC1();
static void LDC2();
static void LD();
static void SWC1();
static void SDC2();
static void SD();
void J();
void JAL();
void BEQ();
void BNE();
void BLEZ();
void BGTZ();
void ADDI();
void ADDIU();
void SLTI();
void SLTIU();
void ANDI();
void ORI();
void XORI();
void LUI();
void COP0();
void COP1();
void COP2();
void BEQL();
void BNEL();
void BLEZL();
void BGTZL();
void DADDIU();
void LDL();
void LDR();
void LB();
void LH();
void LWL();
void LW();
void LBU();
void LHU();
void LWR();
void LWU();
void SB();
void SH();
void SWL();
void SW();
void SDL();
void SDR();
void SWR();
void CACHE();
void LWC1();
void LDC2();
void LD();
void SWC1();
void SDC2();
void SD();
//Special
static void SLL();
static void SRL();
static void SRA();
static void SLLV();
static void SRLV();
static void SRAV();
static void JR();
static void JALR();
static void MOVZ();
static void MOVN();
static void SYSCALL();
static void BREAK();
static void SYNC();
static void DSLLV();
static void DSRLV();
static void MFHI();
static void MTHI();
static void MFLO();
static void MTLO();
static void MULT();
static void MULTU();
static void DIV();
static void DIVU();
static void ADD();
static void ADDU();
static void SUB();
static void SUBU();
static void AND();
static void OR();
static void XOR();
static void NOR();
static void SLT();
static void SLTU();
static void DADDU();
static void DSUBU();
static void DSLL();
static void DSRL();
static void DSRA();
static void DSLL32();
static void DSRL32();
static void DSRA32();
void SLL();
void SRL();
void SRA();
void SLLV();
void SRLV();
void SRAV();
void JR();
void JALR();
void MOVZ();
void MOVN();
void SYSCALL();
void BREAK();
void SYNC();
void DSLLV();
void DSRLV();
void MFHI();
void MTHI();
void MFLO();
void MTLO();
void MULT();
void MULTU();
void DIV();
void DIVU();
void ADD();
void ADDU();
void SUB();
void SUBU();
void AND();
void OR();
void XOR();
void NOR();
void SLT();
void SLTU();
void DADDU();
void DSUBU();
void DSLL();
void DSRL();
void DSRA();
void DSLL32();
void DSRL32();
void DSRA32();
//Special2
//RegImm
static void BLTZ();
static void BGEZ();
static void BLTZL();
static void BGEZL();
void BLTZ();
void BGEZ();
void BLTZL();
void BGEZL();
//Reflection tables
static MIPSReflection::INSTRUCTION m_cReflGeneral[64];
static MIPSReflection::INSTRUCTION m_cReflSpecial[64];
static MIPSReflection::INSTRUCTION m_cReflRegImm[32];
//Opcode tables
typedef void (CMA_MIPSIV::*InstructionFuncConstant)();
static InstructionFuncConstant m_cOpGeneral[MAX_GENERAL_OPS];
static InstructionFuncConstant m_cOpSpecial[MAX_SPECIAL_OPS];
static InstructionFuncConstant m_cOpRegImm[MAX_REGIMM_OPS];
//Reflection tables
static MIPSReflection::INSTRUCTION m_cReflGeneral[MAX_GENERAL_OPS];
static MIPSReflection::INSTRUCTION m_cReflSpecial[MAX_SPECIAL_OPS];
static MIPSReflection::INSTRUCTION m_cReflRegImm[MAX_REGIMM_OPS];
};
extern CMA_MIPSIV g_MAMIPSIV;
#endif

View File

@ -5,7 +5,39 @@
using namespace std;
void CMA_MIPSIV::Template_LoadUnsigned32::operator()(void* pProxyFunction)
void CMA_MIPSIV::Template_Add32(bool isSigned)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->Add();
if(m_regSize == MIPS_REGSIZE_64)
{
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
}
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
}
void CMA_MIPSIV::Template_Sub32(bool isSigned)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->Sub();
if(m_regSize == MIPS_REGSIZE_64)
{
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
}
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
}
void CMA_MIPSIV::Template_LoadUnsigned32(void* pProxyFunction)
{
//TODO: Need to check if this used correctly... LBU, LHU and LW uses this (why LW? and why sign extend on LBU and LHU?)
@ -15,35 +47,46 @@ void CMA_MIPSIV::Template_LoadUnsigned32::operator()(void* pProxyFunction)
m_codeGen->PushIdx(1);
m_codeGen->Call(pProxyFunction, 2, true);
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
if(m_regSize == MIPS_REGSIZE_64)
{
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
}
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PullTop();
}
void CMA_MIPSIV::Template_ShiftCst32::operator()(const OperationFunctionType& Function) const
void CMA_MIPSIV::Template_ShiftCst32(const TemplateParamedOperationFunctionType& Function)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
Function(m_nSA);
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
if(m_regSize == MIPS_REGSIZE_64)
{
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
}
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
}
void CMA_MIPSIV::Template_ShiftVar32::operator()(const OperationFunctionType& function) const
void CMA_MIPSIV::Template_ShiftVar32(const TemplateOperationFunctionType& function)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
function();
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
if(m_regSize == MIPS_REGSIZE_64)
{
m_codeGen->SeX();
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
}
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
}
void CMA_MIPSIV::Template_Mult32::operator()(const OperationFunctionType& Function, unsigned int unit) const
void CMA_MIPSIV::Template_Mult32(const TemplateOperationFunctionType& Function, unsigned int unit)
{
size_t lo[2];
size_t hi[2];
@ -90,7 +133,7 @@ void CMA_MIPSIV::Template_Mult32::operator()(const OperationFunctionType& Functi
}
}
void CMA_MIPSIV::Template_Div32::operator()(const OperationFunctionType& function, unsigned int unit) const
void CMA_MIPSIV::Template_Div32(const TemplateOperationFunctionType& function, unsigned int unit)
{
size_t lo[2];
size_t hi[2];
@ -148,32 +191,143 @@ void CMA_MIPSIV::Template_Div32::operator()(const OperationFunctionType& functio
m_codeGen->EndIf();
}
void CMA_MIPSIV::Template_MovEqual::operator()(bool isEqual) const
void CMA_MIPSIV::Template_MovEqual(bool isEqual)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
if(m_regSize == MIPS_REGSIZE_32)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
}
else
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
m_codeGen->PushCst(0);
m_codeGen->PushCst(0);
m_codeGen->PushCst(0);
m_codeGen->PushCst(0);
m_codeGen->Cmp64(CCodeGen::CONDITION_EQ);
m_codeGen->Cmp64(CCodeGen::CONDITION_EQ);
}
m_codeGen->BeginIf(isEqual);
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
if(m_regSize == MIPS_REGSIZE_64)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
}
}
m_codeGen->EndIf();
}
void CMA_MIPSIV::Template_BranchGez::operator()(bool condition, bool likely) const
void CMA_MIPSIV::Template_SetLessThanImm(bool isSigned)
{
CCodeGen::CONDITION condition = isSigned ? CCodeGen::CONDITION_LT : CCodeGen::CONDITION_BL;
if(m_regSize == MIPS_REGSIZE_32)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushCst(static_cast<int16>(m_nImmediate));
m_codeGen->Cmp(condition);
}
else
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushCst(static_cast<int16>(m_nImmediate));
m_codeGen->PushCst(m_nImmediate & 0x8000 ? 0xFFFFFFFF : 0x00000000);
m_codeGen->Cmp64(condition);
}
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
if(m_regSize == MIPS_REGSIZE_64)
{
//Clear higher 32-bits
m_codeGen->PushCst(0);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
}
}
void CMA_MIPSIV::Template_SetLessThanReg(bool isSigned)
{
CCodeGen::CONDITION condition = isSigned ? CCodeGen::CONDITION_LT : CCodeGen::CONDITION_BL;
if(m_regSize == MIPS_REGSIZE_32)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->Cmp(condition);
}
else
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
m_codeGen->Cmp64(condition);
}
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
if(m_regSize == MIPS_REGSIZE_64)
{
//Clear higher 32-bits
m_codeGen->PushCst(0);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
}
}
void CMA_MIPSIV::Template_BranchEq(bool condition, bool likely)
{
if(m_regSize == MIPS_REGSIZE_32)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->Cmp(CCodeGen::CONDITION_EQ);
}
else if(m_regSize == MIPS_REGSIZE_64)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
m_codeGen->Cmp64(CCodeGen::CONDITION_EQ);
}
if(likely)
{
BranchLikely(condition);
}
else
{
Branch(condition);
}
}
void CMA_MIPSIV::Template_BranchGez(bool condition, bool likely)
{
m_codeGen->PushCst(0);
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
if(m_regSize == MIPS_REGSIZE_32)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
}
else
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
}
m_codeGen->PushCst(0x80000000);
m_codeGen->And();
@ -189,15 +343,24 @@ void CMA_MIPSIV::Template_BranchGez::operator()(bool condition, bool likely) con
}
}
void CMA_MIPSIV::Template_BranchLez::operator()(bool condition, bool likely) const
void CMA_MIPSIV::Template_BranchLez(bool condition, bool likely)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
if(m_regSize == MIPS_REGSIZE_32)
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushCst(0);
m_codeGen->Cmp(CCodeGen::CONDITION_LE);
}
else
{
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
m_codeGen->PushCst(0);
m_codeGen->PushCst(0);
m_codeGen->PushCst(0);
m_codeGen->PushCst(0);
m_codeGen->Cmp64(CCodeGen::CONDITION_LE);
m_codeGen->Cmp64(CCodeGen::CONDITION_LE);
}
if(likely)
{

View File

@ -1,11 +1,6 @@
#include "MA_VU.h"
#include "MIPS.h"
CCodeGen* CMA_VU::m_codeGen = NULL;
CMIPS* CMA_VU::m_pCtx = NULL;
uint32 CMA_VU::m_nOpcode = 0;
uint32 CMA_VU::m_nAddress = 0;
CMA_VU::CMA_VU(bool maskDataAddress) :
CMIPSArchitecture(MIPS_REGSIZE_64),
m_Lower(maskDataAddress)
@ -18,25 +13,17 @@ CMA_VU::~CMA_VU()
}
void CMA_VU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx, bool nParent)
void CMA_VU::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx)
{
if(nParent)
{
//SetupQuickVariables(nAddress, pBlock, pCtx);
//TODO: Get rid of static storage...
m_pCtx = pCtx;
m_codeGen = codeGen;
m_nAddress = nAddress;
m_nOpcode = m_pCtx->m_pMemoryMap->GetInstruction(m_nAddress);
}
SetupQuickVariables(nAddress, codeGen, pCtx);
if(nAddress & 0x04)
if(nAddress & 0x04)
{
m_Upper.CompileInstruction(nAddress, codeGen, pCtx, nParent);
m_Upper.CompileInstruction(nAddress, codeGen, pCtx);
}
else
{
m_Lower.CompileInstruction(nAddress, codeGen, pCtx, nParent);
m_Lower.CompileInstruction(nAddress, codeGen, pCtx);
}
}

View File

@ -12,7 +12,7 @@ class CMA_VU : public CMIPSArchitecture
public:
CMA_VU(bool);
virtual ~CMA_VU();
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*, bool);
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*);
virtual void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
virtual void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
virtual bool IsInstructionBranch(CMIPS*, uint32, uint32);
@ -21,90 +21,94 @@ public:
private:
void SetupReflectionTables();
class CUpper
class CUpper : public CMIPSInstructionFactory
{
public:
CUpper();
void SetupReflectionTables();
void CompileInstruction(uint32, CCodeGen*, CMIPS*, bool);
void CompileInstruction(uint32, CCodeGen*, CMIPS*);
void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
bool IsInstructionBranch(CMIPS*, uint32, uint32);
uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32);
private:
static void (*m_pOpVector[0x40])();
static void (*m_pOpVector0[0x20])();
static void (*m_pOpVector1[0x20])();
static void (*m_pOpVector2[0x20])();
static void (*m_pOpVector3[0x20])();
typedef void (CUpper::*InstructionFuncConstant)();
static uint8 m_nFT;
static uint8 m_nFS;
static uint8 m_nFD;
static uint8 m_nBc;
static uint8 m_nDest;
static InstructionFuncConstant m_pOpVector[0x40];
static InstructionFuncConstant m_pOpVector0[0x20];
static InstructionFuncConstant m_pOpVector1[0x20];
static InstructionFuncConstant m_pOpVector2[0x20];
static InstructionFuncConstant m_pOpVector3[0x20];
uint8 m_nFT;
uint8 m_nFS;
uint8 m_nFD;
uint8 m_nBc;
uint8 m_nDest;
static void ReflOpFtFs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
static void LOI(uint32);
void LOI(uint32);
//Vector
static void ADDbc();
static void SUBbc();
static void MADDbc();
static void MSUBbc();
static void MAXbc();
static void MINIbc();
static void MULbc();
static void MULq();
static void MULi();
static void MINIi();
static void ADDq();
static void MADDq();
static void ADDi();
static void SUBi();
static void MSUBi();
static void ADD();
static void MADD();
static void MUL();
static void MAX();
static void SUB();
static void OPMSUB();
static void MINI();
static void VECTOR0();
static void VECTOR1();
static void VECTOR2();
static void VECTOR3();
void ADDbc();
void SUBbc();
void MADDbc();
void MSUBbc();
void MAXbc();
void MINIbc();
void MULbc();
void MULq();
void MULi();
void MINIi();
void ADDq();
void MADDq();
void ADDi();
void SUBi();
void MSUBi();
void ADD();
void MADD();
void MUL();
void MAX();
void SUB();
void OPMSUB();
void MINI();
void VECTOR0();
void VECTOR1();
void VECTOR2();
void VECTOR3();
//Vector X Common
static void ADDAbc();
static void MADDAbc();
static void MSUBAbc();
static void MULAbc();
void ADDAbc();
void MADDAbc();
void MSUBAbc();
void MULAbc();
//Vector 0
static void ITOF0();
static void FTOI0();
static void ADDA();
void ITOF0();
void FTOI0();
void ADDA();
//Vector 1
static void ITOF4();
static void FTOI4();
static void ABS();
static void MADDA();
void ITOF4();
void FTOI4();
void ABS();
void MADDA();
//Vector 2
static void ITOF12();
static void FTOI12();
static void MULAi();
static void MULA();
static void OPMULA();
void ITOF12();
void FTOI12();
void MULAi();
void MULA();
void OPMULA();
//Vector 3
static void CLIP();
static void MADDAi();
static void MSUBAi();
static void NOP();
void CLIP();
void MADDAi();
void MSUBAi();
void NOP();
MIPSReflection::INSTRUCTION m_ReflV[64];
MIPSReflection::INSTRUCTION m_ReflVX0[32];
@ -125,14 +129,14 @@ private:
static MIPSReflection::INSTRUCTION m_cReflVX3[32];
};
class CLower
class CLower : public CMIPSInstructionFactory
{
public:
CLower(bool);
virtual ~CLower();
void SetupReflectionTables();
void CompileInstruction(uint32, CCodeGen*, CMIPS*, bool);
void CompileInstruction(uint32, CCodeGen*, CMIPS*);
void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
bool IsInstructionBranch(CMIPS*, uint32, uint32);
@ -142,30 +146,32 @@ private:
static void SetQuadWord(uint32, CMIPS*, uint32, uint32);
private:
static void (*m_pOpGeneral[0x80])();
static void (*m_pOpLower[0x40])();
static void (*m_pOpVector0[0x20])();
static void (*m_pOpVector1[0x20])();
static void (*m_pOpVector2[0x20])();
static void (*m_pOpVector3[0x20])();
typedef void (CLower::*InstructionFuncConstant)();
static uint8 m_nIT;
static uint8 m_nIS;
static uint8 m_nID;
static uint8 m_nFSF;
static uint8 m_nFTF;
static uint8 m_nDest;
static uint8 m_nImm5;
static uint16 m_nImm11;
static uint16 m_nImm12;
static uint16 m_nImm15;
static uint16 m_nImm15S;
static uint32 m_nImm24;
static InstructionFuncConstant m_pOpGeneral[0x80];
static InstructionFuncConstant m_pOpLower[0x40];
static InstructionFuncConstant m_pOpVector0[0x20];
static InstructionFuncConstant m_pOpVector1[0x20];
static InstructionFuncConstant m_pOpVector2[0x20];
static InstructionFuncConstant m_pOpVector3[0x20];
static uint32 GetDestOffset(uint8);
static void SetBranchAddress(bool, int32);
static void PushIntegerRegister(unsigned int);
static void ComputeMemAccessAddr(unsigned int, uint32, uint32);
uint8 m_nIT;
uint8 m_nIS;
uint8 m_nID;
uint8 m_nFSF;
uint8 m_nFTF;
uint8 m_nDest;
uint8 m_nImm5;
uint16 m_nImm11;
uint16 m_nImm12;
uint16 m_nImm15;
uint16 m_nImm15S;
uint32 m_nImm24;
uint32 GetDestOffset(uint8);
void SetBranchAddress(bool, int32);
void PushIntegerRegister(unsigned int);
void ComputeMemAccessAddr(unsigned int, uint32, uint32);
static void ReflOpIs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
static void ReflOpIsOfs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
@ -198,68 +204,68 @@ private:
static uint32 ReflEaIs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
//General
static void LQ();
static void SQ();
static void ILW();
static void ISW();
static void IADDIU();
static void ISUBIU();
static void FCSET();
static void FCAND();
static void FCOR();
static void FSAND();
static void FMAND();
static void FCGET();
static void B();
static void BAL();
static void JR();
static void JALR();
static void IBEQ();
static void IBNE();
static void IBLTZ();
static void IBGTZ();
static void IBLEZ();
static void IBGEZ();
static void LOWEROP();
void LQ();
void SQ();
void ILW();
void ISW();
void IADDIU();
void ISUBIU();
void FCSET();
void FCAND();
void FCOR();
void FSAND();
void FMAND();
void FCGET();
void B();
void BAL();
void JR();
void JALR();
void IBEQ();
void IBNE();
void IBLTZ();
void IBGTZ();
void IBLEZ();
void IBGEZ();
void LOWEROP();
//LowerOp
static void IADD();
static void ISUB();
static void IADDI();
static void IAND();
static void IOR();
static void VECTOR0();
static void VECTOR1();
static void VECTOR2();
static void VECTOR3();
void IADD();
void ISUB();
void IADDI();
void IAND();
void IOR();
void VECTOR0();
void VECTOR1();
void VECTOR2();
void VECTOR3();
//Vector0
static void MOVE();
static void LQI();
static void DIV();
static void MTIR();
static void MFP();
static void XTOP();
static void XGKICK();
static void ESIN();
void MOVE();
void LQI();
void DIV();
void MTIR();
void MFP();
void XTOP();
void XGKICK();
void ESIN();
//Vector1
static void MR32();
static void SQI();
static void MFIR();
static void RGET();
static void XITOP();
void MR32();
void SQI();
void MFIR();
void RGET();
void XITOP();
//Vector2
static void RSQRT();
static void ILWR();
static void RINIT();
static void ERCPR();
void RSQRT();
void ILWR();
void RINIT();
void ERCPR();
//Vector3
static void WAITQ();
static void ERLENG();
static void WAITP();
void WAITQ();
void ERLENG();
void WAITP();
MIPSReflection::INSTRUCTION m_ReflGeneral[128];
MIPSReflection::INSTRUCTION m_ReflV[64];
@ -287,11 +293,6 @@ private:
CUpper m_Upper;
CLower m_Lower;
static CCodeGen* m_codeGen;
static CMIPS* m_pCtx;
static uint32 m_nOpcode;
static uint32 m_nAddress;
};
#endif

View File

@ -9,21 +9,21 @@
using namespace std;
uint8 CMA_VU::CLower::m_nImm5;
uint16 CMA_VU::CLower::m_nImm11;
uint16 CMA_VU::CLower::m_nImm12;
uint16 CMA_VU::CLower::m_nImm15;
uint16 CMA_VU::CLower::m_nImm15S;
uint32 CMA_VU::CLower::m_nImm24;
uint8 CMA_VU::CLower::m_nIT;
uint8 CMA_VU::CLower::m_nIS;
uint8 CMA_VU::CLower::m_nID;
uint8 CMA_VU::CLower::m_nFSF;
uint8 CMA_VU::CLower::m_nFTF;
uint8 CMA_VU::CLower::m_nDest;
CMA_VU::CLower::CLower(bool maskDataAddress) :
m_maskDataAddress(maskDataAddress)
CMIPSInstructionFactory(MIPS_REGSIZE_32),
m_maskDataAddress(maskDataAddress),
m_nImm5(0),
m_nImm11(0),
m_nImm12(0),
m_nImm15(0),
m_nImm15S(0),
m_nImm24(0),
m_nIT(0),
m_nIS(0),
m_nID(0),
m_nFSF(0),
m_nFTF(0),
m_nDest(0)
{
}
@ -108,8 +108,10 @@ void CMA_VU::CLower::ComputeMemAccessAddr(unsigned int baseRegister, uint32 base
}
}
void CMA_VU::CLower::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx, bool nParent)
void CMA_VU::CLower::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx)
{
SetupQuickVariables(nAddress, codeGen, pCtx);
uint32 nPrevOpcode = pCtx->m_pMemoryMap->GetInstruction(nAddress - 8);
uint32 nNextOpcode = pCtx->m_pMemoryMap->GetInstruction(nAddress + 4);
@ -135,7 +137,7 @@ void CMA_VU::CLower::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIP
if(m_nOpcode != 0x8000033C)
{
m_pOpGeneral[m_nOpcode >> 25]();
((this)->*(m_pOpGeneral[m_nOpcode >> 25]))();
}
}
@ -496,7 +498,7 @@ void CMA_VU::CLower::IBGEZ()
//40
void CMA_VU::CLower::LOWEROP()
{
m_pOpLower[m_nOpcode & 0x3F]();
((this)->*(m_pOpLower[m_nOpcode & 0x3F]))();
}
//////////////////////////////////////////////////
@ -551,25 +553,25 @@ void CMA_VU::CLower::IOR()
//3C
void CMA_VU::CLower::VECTOR0()
{
m_pOpVector0[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVector0[(m_nOpcode >> 6) & 0x1F]))();
}
//3D
void CMA_VU::CLower::VECTOR1()
{
m_pOpVector1[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVector1[(m_nOpcode >> 6) & 0x1F]))();
}
//3E
void CMA_VU::CLower::VECTOR2()
{
m_pOpVector2[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVector2[(m_nOpcode >> 6) & 0x1F]))();
}
//3F
void CMA_VU::CLower::VECTOR3()
{
m_pOpVector3[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVector3[(m_nOpcode >> 6) & 0x1F]))();
}
//////////////////////////////////////////////////
@ -843,106 +845,106 @@ void CMA_VU::CLower::WAITP()
//Opcode Tables
//////////////////////////////////////////////////
void (*CMA_VU::CLower::m_pOpGeneral[0x80])() =
CMA_VU::CLower::InstructionFuncConstant CMA_VU::CLower::m_pOpGeneral[0x80] =
{
//0x00
LQ, SQ, Illegal, Illegal, ILW, ISW, Illegal, Illegal,
&LQ, &SQ, &Illegal, &Illegal, &ILW, &ISW, &Illegal, &Illegal,
//0x08
IADDIU, ISUBIU, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&IADDIU, &ISUBIU, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, FCSET, FCAND, FCOR, Illegal, Illegal, FSAND, Illegal,
&Illegal, &FCSET, &FCAND, &FCOR, &Illegal, &Illegal, &FSAND, &Illegal,
//0x18
Illegal, Illegal, FMAND, Illegal, FCGET, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &FMAND, &Illegal, &FCGET, &Illegal, &Illegal, &Illegal,
//0x20
B, BAL, Illegal, Illegal, JR, JALR, Illegal, Illegal,
&B, &BAL, &Illegal, &Illegal, &JR, &JALR, &Illegal, &Illegal,
//0x28
IBEQ, IBNE, Illegal, Illegal, IBLTZ, IBGTZ, IBLEZ, IBGEZ,
&IBEQ, &IBNE, &Illegal, &Illegal, &IBLTZ, &IBGTZ, &IBLEZ, &IBGEZ,
//0x30
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x38
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x40
LOWEROP, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&LOWEROP, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x48
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x50
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x58
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x60
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x68
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x70
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x78
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CMA_VU::CLower::m_pOpLower[0x40])() =
CMA_VU::CLower::InstructionFuncConstant CMA_VU::CLower::m_pOpLower[0x40] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x20
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x28
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x30
IADD, ISUB, IADDI, Illegal, IAND, IOR, Illegal, Illegal,
&IADD, &ISUB, &IADDI, &Illegal, &IAND, &IOR, &Illegal, &Illegal,
//0x38
Illegal, Illegal, Illegal, Illegal, VECTOR0, VECTOR1, VECTOR2, VECTOR3,
&Illegal, &Illegal, &Illegal, &Illegal, &VECTOR0, &VECTOR1, &VECTOR2, &VECTOR3,
};
void (*CMA_VU::CLower::m_pOpVector0[0x20])() =
CMA_VU::CLower::InstructionFuncConstant CMA_VU::CLower::m_pOpVector0[0x20] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, MOVE, LQI, DIV, MTIR,
&Illegal, &Illegal, &Illegal, &Illegal, &MOVE, &LQI, &DIV, &MTIR,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, MFP, XTOP, XGKICK, Illegal, Illegal, Illegal, ESIN,
&Illegal, &MFP, &XTOP, &XGKICK, &Illegal, &Illegal, &Illegal, &ESIN,
};
void (*CMA_VU::CLower::m_pOpVector1[0x20])() =
CMA_VU::CLower::InstructionFuncConstant CMA_VU::CLower::m_pOpVector1[0x20] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, MR32, SQI, Illegal, MFIR,
&Illegal, &Illegal, &Illegal, &Illegal, &MR32, &SQI, &Illegal, &MFIR,
//0x10
RGET, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&RGET, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, XITOP, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &XITOP, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CMA_VU::CLower::m_pOpVector2[0x20])() =
CMA_VU::CLower::InstructionFuncConstant CMA_VU::CLower::m_pOpVector2[0x20] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, RSQRT, ILWR,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &RSQRT, &ILWR,
//0x10
RINIT, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&RINIT, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, ERCPR, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &ERCPR, &Illegal,
};
void (*CMA_VU::CLower::m_pOpVector3[0x20])() =
CMA_VU::CLower::InstructionFuncConstant CMA_VU::CLower::m_pOpVector3[0x20] =
{
//0x00
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, WAITQ, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &WAITQ, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, ERLENG, Illegal, WAITP, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &ERLENG, &Illegal, &WAITP, &Illegal,
};

View File

@ -6,14 +6,21 @@
using namespace std;
uint8 CMA_VU::CUpper::m_nFT;
uint8 CMA_VU::CUpper::m_nFS;
uint8 CMA_VU::CUpper::m_nFD;
uint8 CMA_VU::CUpper::m_nBc;
uint8 CMA_VU::CUpper::m_nDest;
void CMA_VU::CUpper::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx, bool nParent)
CMA_VU::CUpper::CUpper() :
CMIPSInstructionFactory(MIPS_REGSIZE_32),
m_nFT(0),
m_nFS(0),
m_nFD(0),
m_nBc(0),
m_nDest(0)
{
}
void CMA_VU::CUpper::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx)
{
SetupQuickVariables(nAddress, codeGen, pCtx);
m_nDest = (uint8 )((m_nOpcode >> 21) & 0x000F);
m_nFT = (uint8 )((m_nOpcode >> 16) & 0x001F);
m_nFS = (uint8 )((m_nOpcode >> 11) & 0x001F);
@ -21,7 +28,7 @@ void CMA_VU::CUpper::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIP
m_nBc = (uint8 )((m_nOpcode >> 0) & 0x0003);
m_pOpVector[m_nOpcode & 0x3F]();
((this)->*(m_pOpVector[m_nOpcode & 0x3F]))();
if(m_nOpcode & 0x80000000)
{
@ -202,25 +209,25 @@ void CMA_VU::CUpper::MINI()
//3C
void CMA_VU::CUpper::VECTOR0()
{
m_pOpVector0[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVector0[(m_nOpcode >> 6) & 0x1F]))();
}
//3D
void CMA_VU::CUpper::VECTOR1()
{
m_pOpVector1[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVector1[(m_nOpcode >> 6) & 0x1F]))();
}
//3E
void CMA_VU::CUpper::VECTOR2()
{
m_pOpVector2[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVector2[(m_nOpcode >> 6) & 0x1F]))();
}
//3F
void CMA_VU::CUpper::VECTOR3()
{
m_pOpVector3[(m_nOpcode >> 6) & 0x1F]();
((this)->*(m_pOpVector3[(m_nOpcode >> 6) & 0x1F]))();
}
//////////////////////////////////////////////////
@ -367,70 +374,70 @@ void CMA_VU::CUpper::NOP()
//Opcode Tables
//////////////////////////////////////////////////
void (*CMA_VU::CUpper::m_pOpVector[0x40])() =
CMA_VU::CUpper::InstructionFuncConstant CMA_VU::CUpper::m_pOpVector[0x40] =
{
//0x00
ADDbc, ADDbc, ADDbc, ADDbc, SUBbc, SUBbc, SUBbc, SUBbc,
&ADDbc, &ADDbc, &ADDbc, &ADDbc, &SUBbc, &SUBbc, &SUBbc, &SUBbc,
//0x08
MADDbc, MADDbc, MADDbc, MADDbc, MSUBbc, MSUBbc, MSUBbc, MSUBbc,
&MADDbc, &MADDbc, &MADDbc, &MADDbc, &MSUBbc, &MSUBbc, &MSUBbc, &MSUBbc,
//0x10
MAXbc, Illegal, Illegal, MAXbc, Illegal, Illegal, Illegal, MINIbc,
&MAXbc, &Illegal, &Illegal, &MAXbc, &Illegal, &Illegal, &Illegal, &MINIbc,
//0x18
MULbc, MULbc, MULbc, MULbc, MULq, Illegal, MULi, MINIi,
&MULbc, &MULbc, &MULbc, &MULbc, &MULq, &Illegal, &MULi, &MINIi,
//0x20
ADDq, MADDq, ADDi, Illegal, Illegal, Illegal, SUBi, MSUBi,
&ADDq, &MADDq, &ADDi, &Illegal, &Illegal, &Illegal, &SUBi, &MSUBi,
//0x28
ADD, MADD, MUL, MAX, SUB, Illegal, OPMSUB, MINI,
&ADD, &MADD, &MUL, &MAX, &SUB, &Illegal, &OPMSUB, &MINI,
//0x30
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x38
Illegal, Illegal, Illegal, Illegal, VECTOR0, VECTOR1, VECTOR2, VECTOR3,
&Illegal, &Illegal, &Illegal, &Illegal, &VECTOR0, &VECTOR1, &VECTOR2, &VECTOR3,
};
void (*CMA_VU::CUpper::m_pOpVector0[0x20])() =
CMA_VU::CUpper::InstructionFuncConstant CMA_VU::CUpper::m_pOpVector0[0x20] =
{
//0x00
ADDAbc, Illegal, Illegal, MSUBAbc, ITOF0, FTOI0, MULAbc, Illegal,
&ADDAbc, &Illegal, &Illegal, &MSUBAbc, &ITOF0, &FTOI0, &MULAbc, &Illegal,
//0x08
Illegal, Illegal, ADDA, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &ADDA, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CMA_VU::CUpper::m_pOpVector1[0x20])() =
CMA_VU::CUpper::InstructionFuncConstant CMA_VU::CUpper::m_pOpVector1[0x20] =
{
//0x00
ADDAbc, Illegal, MADDAbc, MSUBAbc, ITOF4, FTOI4, MULAbc, ABS,
&ADDAbc, &Illegal, &MADDAbc, &MSUBAbc, &ITOF4, &FTOI4, &MULAbc, &ABS,
//0x08
Illegal, Illegal, MADDA, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &MADDA, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CMA_VU::CUpper::m_pOpVector2[0x20])() =
CMA_VU::CUpper::InstructionFuncConstant CMA_VU::CUpper::m_pOpVector2[0x20] =
{
//0x00
Illegal, Illegal, MADDAbc, MSUBAbc, ITOF12, FTOI12, MULAbc, MULAi,
&Illegal, &Illegal, &MADDAbc, &MSUBAbc, &ITOF12, &FTOI12, &MULAbc, &MULAi,
//0x08
Illegal, Illegal, MULA, OPMULA, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &MULA, &OPMULA, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
void (*CMA_VU::CUpper::m_pOpVector3[0x20])() =
CMA_VU::CUpper::InstructionFuncConstant CMA_VU::CUpper::m_pOpVector3[0x20] =
{
//0x00
Illegal, Illegal, MADDAbc, MSUBAbc, Illegal, Illegal, MULAbc, CLIP,
&Illegal, &Illegal, &MADDAbc, &MSUBAbc, &Illegal, &Illegal, &MULAbc, &CLIP,
//0x08
MADDAi, MSUBAi, Illegal, NOP, Illegal, Illegal, Illegal, Illegal,
&MADDAi, &MSUBAi, &Illegal, &NOP, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};

View File

@ -8,14 +8,14 @@
using namespace std;
CMIPS* CMIPSInstructionFactory::m_pCtx = NULL;
CCodeGen* CMIPSInstructionFactory::m_codeGen = NULL;
uint32 CMIPSInstructionFactory::m_nAddress = 0;
uint32 CMIPSInstructionFactory::m_nOpcode = 0;
CMIPSInstructionFactory::CMIPSInstructionFactory(MIPS_REGSIZE nRegSize)
CMIPSInstructionFactory::CMIPSInstructionFactory(MIPS_REGSIZE nRegSize) :
m_pCtx(NULL),
m_codeGen(NULL),
m_nAddress(0),
m_nOpcode(0),
m_regSize(nRegSize)
{
assert(nRegSize == MIPS_REGSIZE_64);
}
CMIPSInstructionFactory::~CMIPSInstructionFactory()

View File

@ -17,20 +17,21 @@ class CMIPSInstructionFactory
public:
CMIPSInstructionFactory(MIPS_REGSIZE);
virtual ~CMIPSInstructionFactory();
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*, bool) = 0;
virtual void CompileInstruction(uint32, CCodeGen*, CMIPS*) = 0;
protected:
static void ComputeMemAccessAddr();
static void Branch(bool);
static void BranchLikely(bool);
void ComputeMemAccessAddr();
void Branch(bool);
void BranchLikely(bool);
static void Illegal();
static void SetupQuickVariables(uint32, CCodeGen*, CMIPS*);
void Illegal();
void SetupQuickVariables(uint32, CCodeGen*, CMIPS*);
static CCodeGen* m_codeGen;
static CMIPS* m_pCtx;
static uint32 m_nOpcode;
static uint32 m_nAddress;
CCodeGen* m_codeGen;
CMIPS* m_pCtx;
uint32 m_nOpcode;
uint32 m_nAddress;
MIPS_REGSIZE m_regSize;
};
#endif
#endif

View File

@ -10,10 +10,6 @@
#include "iop/Iop_SifManPs2.h"
#include "VIF.h"
#include "Timer.h"
#include "MA_EE.h"
#include "COP_SCU.h"
#include "COP_FPU.h"
#include "COP_VU.h"
#include "PtrMacro.h"
#include "StdStream.h"
#include "GZipStream.h"
@ -101,6 +97,9 @@ m_sif(m_dmac, m_pRAM, m_iop.m_ram),
m_vif(m_gif, m_pRAM, CVIF::VPUINIT(m_pMicroMem0, m_pVUMem0, &m_VU0), CVIF::VPUINIT(m_pMicroMem1, m_pVUMem1, &m_VU1)),
m_intc(m_dmac),
m_timer(m_intc),
m_COP_SCU(MIPS_REGSIZE_64),
m_COP_FPU(MIPS_REGSIZE_64),
m_COP_VU(MIPS_REGSIZE_64),
m_MAVU0(false),
m_MAVU1(true)
{
@ -109,14 +108,20 @@ m_MAVU1(true)
CAppConfig::GetInstance().RegisterPreferenceString(PREF_PS2_MC1_DIRECTORY, PREF_PS2_MC1_DIRECTORY_DEFAULT);
CAppConfig::GetInstance().RegisterPreferenceInteger(PREF_PS2_FRAMESKIP, PREF_PS2_FRAMESKIP_DEFAULT);
m_iopOs = new CIopBios(PS2::IOP_CLOCK_FREQ, m_iop.m_cpu, m_iop.m_ram, PS2::IOP_RAM_SIZE);
m_iopOsPtr = Iop::CSubSystem::BiosPtr(new CIopBios(PS2::IOP_CLOCK_FREQ, m_iop.m_cpu, m_iop.m_ram, PS2::IOP_RAM_SIZE));
m_iopOs = static_cast<CIopBios*>(m_iopOsPtr.get());
m_os = new CPS2OS(m_EE, m_pRAM, m_pBIOS, m_pGS, m_sif, *m_iopOs);
}
CPS2VM::~CPS2VM()
{
delete m_os;
delete m_iopOs;
{
//Big hack to force deletion of the IopBios
m_iop.SetBios(Iop::CSubSystem::BiosPtr());
m_iopOs = NULL;
m_iopOsPtr.reset();
}
}
//////////////////////////////////////////////////
@ -359,10 +364,10 @@ void CPS2VM::CreateVM()
m_EE.m_pMemoryMap->InsertInstructionMap(0x00000000, 0x01FFFFFF, m_pRAM, 0x00);
m_EE.m_pMemoryMap->InsertInstructionMap(0x1FC00000, 0x1FFFFFFF, m_pBIOS, 0x01);
m_EE.m_pArch = &g_MAEE;
m_EE.m_pCOP[0] = &g_COPSCU;
m_EE.m_pCOP[1] = &g_COPFPU;
m_EE.m_pCOP[2] = &g_COPVU;
m_EE.m_pArch = &m_EEArch;
m_EE.m_pCOP[0] = &m_COP_SCU;
m_EE.m_pCOP[1] = &m_COP_FPU;
m_EE.m_pCOP[2] = &m_COP_VU;
m_EE.m_handlerParam = this;
m_EE.m_pAddrTranslator = CPS2OS::TranslateAddress;
@ -444,7 +449,7 @@ void CPS2VM::ResetVM()
memset(m_pMicroMem1, 0, PS2::MICROMEM1SIZE);
m_iop.Reset();
m_iop.SetBios(m_iopOs);
m_iop.SetBios(m_iopOsPtr);
//LoadBIOS();

View File

@ -18,6 +18,10 @@
#include "VirtualMachine.h"
#include "MipsExecutor.h"
#include "MA_VU.h"
#include "MA_EE.h"
#include "COP_SCU.h"
#include "COP_FPU.h"
#include "COP_VU.h"
#include "iop/Iop_SubSystem.h"
class CIopBios;
@ -124,6 +128,7 @@ public:
CTimer m_timer;
CPS2OS* m_os;
CIopBios* m_iopOs;
Iop::CSubSystem::BiosPtr m_iopOsPtr;
CMIPS m_EE;
CMIPS m_VU0;
@ -177,6 +182,10 @@ private:
bool m_nEnd;
CMA_VU m_MAVU0;
CMA_VU m_MAVU1;
CMA_EE m_EEArch;
CCOP_SCU m_COP_SCU;
CCOP_FPU m_COP_FPU;
CCOP_VU m_COP_VU;
unsigned int m_frameNumber;
unsigned int m_frameSkip;
bool m_singleStepEe;

View File

@ -504,6 +504,12 @@ void CX86Assembler::SetlEb(const CAddress& address)
WriteEvOp(0x9C, 0x00, false, address);
}
void CX86Assembler::SetleEb(const CAddress& address)
{
WriteByte(0x0F);
WriteEvOp(0x9E, 0x00, false, address);
}
void CX86Assembler::SetgEb(const CAddress& address)
{
WriteByte(0x0F);

View File

@ -164,6 +164,7 @@ public:
void SeteEb(const CAddress&);
void SetneEb(const CAddress&);
void SetlEb(const CAddress&);
void SetleEb(const CAddress&);
void SetgEb(const CAddress&);
void ShrEd(const CAddress&);
void ShrEd(const CAddress&, uint8);

View File

@ -1,6 +1,5 @@
#include "Iop_SubSystem.h"
#include "../MemoryStateFile.h"
#include "../MA_MIPSIV.h"
#include "../Ps2Const.h"
#include "../Log.h"
#include "placeholder_def.h"
@ -18,7 +17,6 @@ using namespace PS2;
CSubSystem::CSubSystem() :
m_cpu(MEMORYMAP_ENDIAN_LSBF, 0, 0x1FFFFFFF),
m_executor(m_cpu),
m_bios(NULL),
m_ram(new uint8[IOP_RAM_SIZE]),
m_scratchPad(new uint8[IOP_SCRATCH_SIZE]),
m_spuRam(new uint8[SPU_RAM_SIZE]),
@ -27,7 +25,8 @@ m_counters(IOP_CLOCK_FREQ, m_intc),
m_spuCore0(m_spuRam, SPU_RAM_SIZE),
m_spuCore1(m_spuRam, SPU_RAM_SIZE),
m_spu(m_spuCore0),
m_spu2(m_spuCore0, m_spuCore1)
m_spu2(m_spuCore0, m_spuCore1),
m_cpuArch(MIPS_REGSIZE_32)
{
//Read memory map
m_cpu.m_pMemoryMap->InsertReadMap((0 * IOP_RAM_SIZE), (0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x01);
@ -51,7 +50,7 @@ m_spu2(m_spuCore0, m_spuCore1)
m_cpu.m_pMemoryMap->InsertInstructionMap((2 * IOP_RAM_SIZE), (2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x03);
m_cpu.m_pMemoryMap->InsertInstructionMap((3 * IOP_RAM_SIZE), (3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x04);
m_cpu.m_pArch = &g_MAMIPSIV;
m_cpu.m_pArch = &m_cpuArch;
m_cpu.m_pAddrTranslator = &CMIPS::TranslateAddress64;
m_dmac.SetReceiveFunction(4, bind(&CSpuBase::ReceiveDma, &m_spuCore0, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3));
@ -63,13 +62,8 @@ CSubSystem::~CSubSystem()
}
void CSubSystem::SetBios(CBiosBase* bios)
void CSubSystem::SetBios(const BiosPtr& bios)
{
if(m_bios != NULL)
{
delete m_bios;
m_bios = NULL;
}
m_bios = bios;
}
@ -103,7 +97,7 @@ void CSubSystem::Reset()
m_counters.Reset();
m_dmac.Reset();
m_intc.Reset();
SetBios(NULL);
m_bios.reset();
m_cpu.m_Comments.RemoveTags();
m_cpu.m_Functions.RemoveTags();

View File

@ -2,6 +2,7 @@
#define _IOP_SUBSYSTEM_H_
#include "../MIPS.h"
#include "../MA_MIPSIV.h"
#include "../MipsExecutor.h"
#include "Iop_SpuBase.h"
#include "Iop_Spu.h"
@ -18,13 +19,15 @@ namespace Iop
class CSubSystem
{
public:
typedef std::tr1::shared_ptr<CBiosBase> BiosPtr;
CSubSystem();
virtual ~CSubSystem();
void Reset();
unsigned int ExecuteCpu(bool);
void SetBios(CBiosBase*);
void SetBios(const BiosPtr&);
virtual void SaveState(CZipArchiveWriter&);
virtual void LoadState(CZipArchiveReader&);
@ -40,8 +43,9 @@ namespace Iop
CSpu m_spu;
CSpu2 m_spu2;
CMIPS m_cpu;
CMA_MIPSIV m_cpuArch;
CMipsExecutor m_executor;
CBiosBase* m_bios;
BiosPtr m_bios;
private:
enum

View File

@ -48,15 +48,15 @@ void CPsfBios::CountTicks(uint32 ticks)
m_bios.CountTicks(ticks);
}
void CPsfBios::SaveState(CZipArchiveWriter& archive)
{
}
void CPsfBios::LoadState(CZipArchiveReader& archive)
{
}
void CPsfBios::SaveState(CZipArchiveWriter& archive)
{
}
void CPsfBios::LoadState(CZipArchiveReader& archive)
{
}
bool CPsfBios::IsIdle()
{

View File

@ -25,9 +25,9 @@ void CPsfLoader::LoadPsf(CPsfVm& virtualMachine, const char* pathString, CPsfBas
void CPsfLoader::LoadPsx(CPsfVm& virtualMachine, const char* pathString, CPsfBase::TagMap* tags)
{
CPsxBios* bios = new CPsxBios(virtualMachine.GetCpu(), virtualMachine.GetRam(), PS2::IOP_RAM_SIZE);
Iop::CSubSystem::BiosPtr bios = Iop::CSubSystem::BiosPtr(new CPsxBios(virtualMachine.GetCpu(), virtualMachine.GetRam(), PS2::IOP_RAM_SIZE));
virtualMachine.SetBios(bios);
LoadPsxRecurse(virtualMachine, bios, pathString, tags);
LoadPsxRecurse(virtualMachine, static_cast<CPsxBios*>(bios.get()), pathString, tags);
}
void CPsfLoader::LoadPsxRecurse(CPsfVm& virtualMachine, CPsxBios* bios, const char* pathString, CPsfBase::TagMap* tags)
@ -87,10 +87,10 @@ void CPsfLoader::LoadPsxRecurse(CPsfVm& virtualMachine, CPsxBios* bios, const ch
void CPsfLoader::LoadPs2(CPsfVm& virtualMachine, const char* pathString, CPsfBase::TagMap* tags)
{
PS2::CPsfBios* bios = new PS2::CPsfBios(virtualMachine.GetCpu(), virtualMachine.GetRam(), PS2::IOP_RAM_SIZE);
Iop::CSubSystem::BiosPtr bios = Iop::CSubSystem::BiosPtr(new PS2::CPsfBios(virtualMachine.GetCpu(), virtualMachine.GetRam(), PS2::IOP_RAM_SIZE));
virtualMachine.SetBios(bios);
LoadPs2Recurse(virtualMachine, bios, pathString, tags);
bios->Start();
LoadPs2Recurse(virtualMachine, static_cast<PS2::CPsfBios*>(bios.get()), pathString, tags);
static_cast<PS2::CPsfBios*>(bios.get())->Start();
}
void CPsfLoader::LoadPs2Recurse(CPsfVm& virtualMachine, PS2::CPsfBios* bios, const char* pathString, CPsfBase::TagMap* tags)

View File

@ -156,7 +156,7 @@ uint8* CPsfVm::GetRam()
return m_iop.m_ram;
}
void CPsfVm::SetBios(Iop::CBiosBase* bios)
void CPsfVm::SetBios(const Iop::CSubSystem::BiosPtr& bios)
{
m_iop.SetBios(bios);
}

View File

@ -31,7 +31,7 @@ public:
Iop::CSpuBase& GetSpuCore(unsigned int);
uint8* GetRam();
void SetBios(Iop::CBiosBase*);
void SetBios(const Iop::CSubSystem::BiosPtr&);
CDebuggable GetDebugInfo();