mirror of
https://github.com/libretro/Play-.git
synced 2024-11-28 03:00:49 +00:00
Added a generic way to distinguish branch instructions that don't have a delay slot (needed for VCALLMS, ERET and SYSCALL) from those who have.
Added a real COP_SCU_Reflection file. git-svn-id: http://svn.purei.org/purei/trunk@821 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
ab85038514
commit
e83a427c11
@ -396,6 +396,10 @@
|
||||
RelativePath=".\Source\COP_SCU.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\COP_SCU_Reflection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\ELF.cpp"
|
||||
>
|
||||
|
@ -12,7 +12,7 @@ public:
|
||||
virtual void GetInstruction(uint32, char*);
|
||||
virtual void GetArguments(uint32, uint32, char*);
|
||||
virtual uint32 GetEffectiveAddress(uint32, uint32);
|
||||
virtual bool IsBranch(uint32);
|
||||
virtual MIPS_BRANCH_TYPE IsBranch(uint32);
|
||||
|
||||
protected:
|
||||
void SetupReflectionTables();
|
||||
|
@ -8,105 +8,81 @@ using namespace MIPSReflection;
|
||||
|
||||
void CCOP_FPU::ReflOpRtFs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint8 nRT, nFS;
|
||||
|
||||
nRT = (uint8) ((nOpcode >> 16) & 0x001F);
|
||||
nFS = (uint8) ((nOpcode >> 11) & 0x001F);
|
||||
uint8 nRT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
||||
|
||||
sprintf(sText, "%s, F%i", CMIPS::m_sGPRName[nRT], nFS);
|
||||
}
|
||||
|
||||
void CCOP_FPU::ReflOpRtFcs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint8 nRT, nFS;
|
||||
|
||||
nRT = (uint8) ((nOpcode >> 16) & 0x001F);
|
||||
nFS = (uint8) ((nOpcode >> 11) & 0x001F);
|
||||
uint8 nRT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
||||
|
||||
sprintf(sText, "%s, FCR%i", CMIPS::m_sGPRName[nRT], nFS);
|
||||
}
|
||||
|
||||
void CCOP_FPU::ReflOpFdFs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint8 nFS, nFD;
|
||||
|
||||
nFS = (uint8) ((nOpcode >> 11) & 0x001F);
|
||||
nFD = (uint8) ((nOpcode >> 6) & 0x001F);
|
||||
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
||||
uint8 nFD = static_cast<uint8>((nOpcode >> 6) & 0x001F);
|
||||
|
||||
sprintf(sText, "F%i, F%i", nFD, nFS);
|
||||
}
|
||||
|
||||
void CCOP_FPU::ReflOpFdFt(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint8 nFD, nFT;
|
||||
|
||||
nFT = (uint8) ((nOpcode >> 16) & 0x001F);
|
||||
nFD = (uint8) ((nOpcode >> 6) & 0x001F);
|
||||
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||
uint8 nFD = static_cast<uint8>((nOpcode >> 6) & 0x001F);
|
||||
|
||||
sprintf(sText, "F%i, F%i", nFD, nFT);
|
||||
}
|
||||
|
||||
void CCOP_FPU::ReflOpFsFt(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint8 nFS, nFT;
|
||||
|
||||
nFS = (uint8) ((nOpcode >> 11) & 0x001F);
|
||||
nFT = (uint8) ((nOpcode >> 16) & 0x001F);
|
||||
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
||||
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||
|
||||
sprintf(sText, "F%i, F%i", nFS, nFT);
|
||||
}
|
||||
|
||||
void CCOP_FPU::ReflOpCcFsFt(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint8 nCC, nFS, nFT;
|
||||
|
||||
nFT = (uint8) ((nOpcode >> 16) & 0x001F);
|
||||
nFS = (uint8) ((nOpcode >> 11) & 0x001F);
|
||||
nCC = (uint8) ((nOpcode >> 8) & 0x0007);
|
||||
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
||||
uint8 nCC = static_cast<uint8>((nOpcode >> 8) & 0x0007);
|
||||
|
||||
sprintf(sText, "CC%i, F%i, F%i", nCC, nFS, nFT);
|
||||
}
|
||||
|
||||
void CCOP_FPU::ReflOpFdFsFt(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint8 nFT, nFS, nFD;
|
||||
|
||||
nFT = (uint8) ((nOpcode >> 16) & 0x001F);
|
||||
nFS = (uint8) ((nOpcode >> 11) & 0x001F);
|
||||
nFD = (uint8) ((nOpcode >> 6) & 0x001F);
|
||||
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
||||
uint8 nFD = static_cast<uint8>((nOpcode >> 6) & 0x001F);
|
||||
|
||||
sprintf(sText, "F%i, F%i, F%i", nFD, nFS, nFT);
|
||||
}
|
||||
|
||||
void CCOP_FPU::ReflOpFtOffRs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint8 nRS, nFT;
|
||||
uint16 nImm;
|
||||
|
||||
nRS = (uint8) ((nOpcode >> 21) & 0x001F);
|
||||
nFT = (uint8) ((nOpcode >> 16) & 0x001F);
|
||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||
uint8 nRS = static_cast<uint8> ((nOpcode >> 21) & 0x001F);
|
||||
uint8 nFT = static_cast<uint8> ((nOpcode >> 16) & 0x001F);
|
||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||
|
||||
sprintf(sText, "F%i, $%0.4X(%s)", nFT, nImm, CMIPS::m_sGPRName[nRS]);
|
||||
}
|
||||
|
||||
void CCOP_FPU::ReflOpCcOff(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint16 nImm;
|
||||
|
||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||
|
||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||
nAddress += 4;
|
||||
|
||||
sprintf(sText, "CC%i, $%0.8X", (nOpcode >> 18) & 0x07, nAddress + CMIPS::GetBranch(nImm));
|
||||
}
|
||||
|
||||
uint32 CCOP_FPU::ReflEaOffset(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
uint16 nImm;
|
||||
|
||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||
|
||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||
nAddress += 4;
|
||||
return (nAddress + CMIPS::GetBranch(nImm));
|
||||
}
|
||||
@ -431,68 +407,50 @@ void CCOP_FPU::SetupReflectionTables()
|
||||
|
||||
void CCOP_FPU::GetInstruction(uint32 nOpcode, char* sText)
|
||||
{
|
||||
INSTRUCTION Instr;
|
||||
unsigned int nCount;
|
||||
CMIPS* pCtx;
|
||||
|
||||
nCount = 256;
|
||||
pCtx = NULL;
|
||||
|
||||
unsigned int nCount = 256;
|
||||
if(nOpcode == 0)
|
||||
{
|
||||
strncpy(sText, "NOP", nCount);
|
||||
return;
|
||||
}
|
||||
|
||||
INSTRUCTION Instr;
|
||||
Instr.pGetMnemonic = SubTableMnemonic;
|
||||
Instr.pSubTable = &m_ReflGeneralTable;
|
||||
Instr.pGetMnemonic(&Instr, pCtx, nOpcode, sText, nCount);
|
||||
Instr.pGetMnemonic(&Instr, NULL, nOpcode, sText, nCount);
|
||||
}
|
||||
|
||||
void CCOP_FPU::GetArguments(uint32 nAddress, uint32 nOpcode, char* sText)
|
||||
{
|
||||
INSTRUCTION Instr;
|
||||
unsigned int nCount;
|
||||
CMIPS* pCtx;
|
||||
|
||||
nCount = 256;
|
||||
pCtx = NULL;
|
||||
|
||||
unsigned int nCount = 256;
|
||||
if(nOpcode == 0)
|
||||
{
|
||||
strncpy(sText, "", nCount);
|
||||
return;
|
||||
}
|
||||
|
||||
INSTRUCTION Instr;
|
||||
Instr.pGetOperands = SubTableOperands;
|
||||
Instr.pSubTable = &m_ReflGeneralTable;
|
||||
Instr.pGetOperands(&Instr, pCtx, nAddress, nOpcode, sText, 256);
|
||||
Instr.pGetOperands(&Instr, NULL, nAddress, nOpcode, sText, nCount);
|
||||
}
|
||||
|
||||
bool CCOP_FPU::IsBranch(uint32 nOpcode)
|
||||
MIPS_BRANCH_TYPE CCOP_FPU::IsBranch(uint32 nOpcode)
|
||||
{
|
||||
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
||||
|
||||
INSTRUCTION Instr;
|
||||
CMIPS* pCtx;
|
||||
|
||||
pCtx = NULL;
|
||||
|
||||
if(nOpcode == 0) return false;
|
||||
|
||||
Instr.pIsBranch = SubTableIsBranch;
|
||||
Instr.pSubTable = &m_ReflGeneralTable;
|
||||
return Instr.pIsBranch(&Instr, pCtx, nOpcode);
|
||||
return Instr.pIsBranch(&Instr, NULL, nOpcode);
|
||||
}
|
||||
|
||||
uint32 CCOP_FPU::GetEffectiveAddress(uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
INSTRUCTION Instr;
|
||||
CMIPS* pCtx;
|
||||
|
||||
pCtx = NULL;
|
||||
|
||||
if(nOpcode == 0) return 0;
|
||||
|
||||
INSTRUCTION Instr;
|
||||
Instr.pGetEffectiveAddress = SubTableEffAddr;
|
||||
Instr.pSubTable = &m_ReflGeneralTable;
|
||||
return Instr.pGetEffectiveAddress(&Instr, pCtx, nAddress, nOpcode);
|
||||
return Instr.pGetEffectiveAddress(&Instr, NULL, nAddress, nOpcode);
|
||||
}
|
||||
|
@ -42,12 +42,12 @@ const char* CCOP_SCU::m_sRegName[] =
|
||||
"*RESERVED*"
|
||||
};
|
||||
|
||||
CCOP_SCU::CCOP_SCU(MIPS_REGSIZE nRegSize) :
|
||||
CMIPSCoprocessor(nRegSize),
|
||||
m_nRT(0),
|
||||
m_nRD(0)
|
||||
CCOP_SCU::CCOP_SCU(MIPS_REGSIZE nRegSize)
|
||||
: CMIPSCoprocessor(nRegSize)
|
||||
, m_nRT(0)
|
||||
, m_nRD(0)
|
||||
{
|
||||
|
||||
SetupReflectionTables();
|
||||
}
|
||||
|
||||
void CCOP_SCU::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx)
|
||||
@ -236,118 +236,3 @@ CCOP_SCU::InstructionFuncConstant CCOP_SCU::m_pOpC0[0x40] =
|
||||
//0x38
|
||||
&CCOP_SCU::EI, &CCOP_SCU::DI, &CCOP_SCU::Illegal, &CCOP_SCU::Illegal, &CCOP_SCU::Illegal, &CCOP_SCU::Illegal, &CCOP_SCU::Illegal, &CCOP_SCU::Illegal,
|
||||
};
|
||||
|
||||
void CCOP_SCU::GetInstruction(uint32 nOpcode, char* sText)
|
||||
{
|
||||
switch((nOpcode >> 21) & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
strcpy(sText, "MFC0");
|
||||
break;
|
||||
case 0x04:
|
||||
strcpy(sText, "MTC0");
|
||||
break;
|
||||
case 0x08:
|
||||
switch((nOpcode >> 16) & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
strcpy(sText, "BC0F");
|
||||
break;
|
||||
case 0x01:
|
||||
strcpy(sText, "BC0T");
|
||||
break;
|
||||
default:
|
||||
strcpy(sText, "???");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x10:
|
||||
switch(nOpcode & 0x3F)
|
||||
{
|
||||
case 0x02:
|
||||
strcpy(sText, "TLBWI");
|
||||
break;
|
||||
case 0x18:
|
||||
strcpy(sText, "ERET");
|
||||
break;
|
||||
case 0x38:
|
||||
strcpy(sText, "EI");
|
||||
break;
|
||||
case 0x39:
|
||||
strcpy(sText, "DI");
|
||||
break;
|
||||
default:
|
||||
strcpy(sText, "???");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
strcpy(sText, "???");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CCOP_SCU::GetArguments(uint32 nAddress, uint32 nOpcode, char* sText)
|
||||
{
|
||||
uint8 nRT = static_cast<uint8>((nOpcode >> 16) & 0x1F);
|
||||
uint8 nRD = static_cast<uint8>((nOpcode >> 11) & 0x1F);
|
||||
uint16 nImm = static_cast<uint16>(nOpcode);
|
||||
switch((nOpcode >> 21) & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x04:
|
||||
sprintf(sText, "%s, %s", CMIPS::m_sGPRName[nRT], m_sRegName[nRD]);
|
||||
break;
|
||||
case 0x08:
|
||||
switch((nOpcode >> 16) & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
sprintf(sText, "0x%0.8X", nAddress + CMIPS::GetBranch(nImm) + 4);
|
||||
break;
|
||||
default:
|
||||
strcpy(sText, "");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
strcpy(sText, "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CCOP_SCU::GetEffectiveAddress(uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
if(((nOpcode >> 21) & 0x1F) == 0x08)
|
||||
{
|
||||
switch((nOpcode >> 16) & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
return (nAddress + CMIPS::GetBranch(static_cast<uint16>(nOpcode)) + 4);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CCOP_SCU::IsBranch(uint32 nOpcode)
|
||||
{
|
||||
if(((nOpcode >> 21) & 0x1F) == 0x08)
|
||||
{
|
||||
switch((nOpcode >> 16) & 0x1F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _COP_SCU_H_
|
||||
|
||||
#include "MIPSCoprocessor.h"
|
||||
#include "MIPSReflection.h"
|
||||
|
||||
class CCOP_SCU : public CMIPSCoprocessor
|
||||
{
|
||||
@ -15,39 +16,64 @@ public:
|
||||
ERROREPC = 0x1E,
|
||||
};
|
||||
|
||||
CCOP_SCU(MIPS_REGSIZE);
|
||||
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*);
|
||||
virtual void GetInstruction(uint32, char*);
|
||||
virtual void GetArguments(uint32, uint32, char*);
|
||||
virtual uint32 GetEffectiveAddress(uint32, uint32);
|
||||
virtual bool IsBranch(uint32);
|
||||
CCOP_SCU(MIPS_REGSIZE);
|
||||
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*);
|
||||
virtual void GetInstruction(uint32, char*);
|
||||
virtual void GetArguments(uint32, uint32, char*);
|
||||
virtual uint32 GetEffectiveAddress(uint32, uint32);
|
||||
virtual MIPS_BRANCH_TYPE IsBranch(uint32);
|
||||
|
||||
static const char* m_sRegName[];
|
||||
|
||||
protected:
|
||||
void SetupReflectionTables();
|
||||
|
||||
static void ReflOpRtRd(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
static void ReflOpCcOff(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
|
||||
static uint32 ReflEaOffset(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||
|
||||
MIPSReflection::INSTRUCTION m_ReflGeneral[64];
|
||||
MIPSReflection::INSTRUCTION m_ReflCop0[32];
|
||||
MIPSReflection::INSTRUCTION m_ReflBc0[4];
|
||||
MIPSReflection::INSTRUCTION m_ReflC0[64];
|
||||
|
||||
MIPSReflection::SUBTABLE m_ReflGeneralTable;
|
||||
MIPSReflection::SUBTABLE m_ReflCop0Table;
|
||||
MIPSReflection::SUBTABLE m_ReflBc0Table;
|
||||
MIPSReflection::SUBTABLE m_ReflC0Table;
|
||||
|
||||
static const char* m_sRegName[];
|
||||
|
||||
private:
|
||||
typedef void (CCOP_SCU::*InstructionFuncConstant)();
|
||||
|
||||
static InstructionFuncConstant m_pOpGeneral[0x20];
|
||||
static InstructionFuncConstant m_pOpBC0[0x20];
|
||||
static InstructionFuncConstant m_pOpC0[0x40];
|
||||
static InstructionFuncConstant m_pOpGeneral[0x20];
|
||||
static InstructionFuncConstant m_pOpBC0[0x20];
|
||||
static InstructionFuncConstant m_pOpC0[0x40];
|
||||
|
||||
uint8 m_nRT;
|
||||
uint8 m_nRD;
|
||||
uint8 m_nRT;
|
||||
uint8 m_nRD;
|
||||
|
||||
//General
|
||||
void MFC0();
|
||||
void MTC0();
|
||||
void BC0();
|
||||
void C0();
|
||||
void MFC0();
|
||||
void MTC0();
|
||||
void BC0();
|
||||
void C0();
|
||||
|
||||
//BC0
|
||||
void BC0F();
|
||||
void BC0T();
|
||||
void BC0F();
|
||||
void BC0T();
|
||||
|
||||
//C0
|
||||
void ERET();
|
||||
void EI();
|
||||
void DI();
|
||||
void ERET();
|
||||
void EI();
|
||||
void DI();
|
||||
|
||||
//Reflection tables
|
||||
static MIPSReflection::INSTRUCTION m_cReflGeneral[64];
|
||||
static MIPSReflection::INSTRUCTION m_cReflCop0[32];
|
||||
static MIPSReflection::INSTRUCTION m_cReflBc0[4];
|
||||
static MIPSReflection::INSTRUCTION m_cReflC0[64];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
314
Source/COP_SCU_Reflection.cpp
Normal file
314
Source/COP_SCU_Reflection.cpp
Normal file
@ -0,0 +1,314 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include "COP_SCU.h"
|
||||
#include "MIPS.h"
|
||||
|
||||
using namespace MIPSReflection;
|
||||
|
||||
void CCOP_SCU::ReflOpRtRd(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint8 nRT = static_cast<uint8>((nOpcode >> 16) & 0x1F);
|
||||
uint8 nRD = static_cast<uint8>((nOpcode >> 11) & 0x1F);
|
||||
|
||||
sprintf(sText, "%s, %s", CMIPS::m_sGPRName[nRT], m_sRegName[nRD]);
|
||||
}
|
||||
|
||||
void CCOP_SCU::ReflOpCcOff(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||
nAddress += 4;
|
||||
sprintf(sText, "CC%i, $%0.8X", (nOpcode >> 18) & 0x07, nAddress + CMIPS::GetBranch(nImm));
|
||||
}
|
||||
|
||||
uint32 CCOP_SCU::ReflEaOffset(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||
nAddress += 4;
|
||||
return (nAddress + CMIPS::GetBranch(nImm));
|
||||
}
|
||||
|
||||
INSTRUCTION CCOP_SCU::m_cReflGeneral[64] =
|
||||
{
|
||||
//0x00
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x08
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x10
|
||||
{ "COP0", NULL, SubTableMnemonic, SubTableOperands, SubTableIsBranch, SubTableEffAddr },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x18
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x20
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x28
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x30
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x38
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
INSTRUCTION CCOP_SCU::m_cReflCop0[32] =
|
||||
{
|
||||
//0x00
|
||||
{ "MFC0", NULL, CopyMnemonic, ReflOpRtRd, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ "MTC0", NULL, CopyMnemonic, ReflOpRtRd, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x08
|
||||
{ "BC0", NULL, SubTableMnemonic, SubTableOperands, SubTableIsBranch, SubTableEffAddr },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x10
|
||||
{ "C0", NULL, SubTableMnemonic, SubTableOperands, SubTableIsBranch, SubTableEffAddr },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x18
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
INSTRUCTION CCOP_SCU::m_cReflBc0[4] =
|
||||
{
|
||||
//0x00
|
||||
{ "BC0F", NULL, CopyMnemonic, ReflOpCcOff, MIPSReflection::IsBranch, ReflEaOffset },
|
||||
{ "BC0T", NULL, CopyMnemonic, ReflOpCcOff, MIPSReflection::IsBranch, ReflEaOffset },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
INSTRUCTION CCOP_SCU::m_cReflC0[64] =
|
||||
{
|
||||
//0x00
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ "TLBWI", NULL, CopyMnemonic, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x08
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x10
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x18
|
||||
{ "ERET", NULL, CopyMnemonic, NULL, IsNoDelayBranch, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x20
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x28
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x30
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x38
|
||||
{ "EI", NULL, CopyMnemonic, NULL, NULL, NULL },
|
||||
{ "DI", NULL, CopyMnemonic, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
void CCOP_SCU::SetupReflectionTables()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(sizeof(m_ReflGeneral) == sizeof(m_cReflGeneral));
|
||||
BOOST_STATIC_ASSERT(sizeof(m_ReflCop0) == sizeof(m_cReflCop0));
|
||||
BOOST_STATIC_ASSERT(sizeof(m_ReflBc0) == sizeof(m_cReflBc0));
|
||||
BOOST_STATIC_ASSERT(sizeof(m_ReflC0) == sizeof(m_cReflC0));
|
||||
|
||||
memcpy(m_ReflGeneral, m_cReflGeneral, sizeof(m_cReflGeneral));
|
||||
memcpy(m_ReflCop0, m_cReflCop0, sizeof(m_cReflCop0));
|
||||
memcpy(m_ReflBc0, m_cReflBc0, sizeof(m_cReflBc0));
|
||||
memcpy(m_ReflC0, m_cReflC0, sizeof(m_cReflC0));
|
||||
|
||||
m_ReflGeneralTable.nShift = 26;
|
||||
m_ReflGeneralTable.nMask = 0x3F;
|
||||
m_ReflGeneralTable.pTable = m_ReflGeneral;
|
||||
|
||||
m_ReflCop0Table.nShift = 21;
|
||||
m_ReflCop0Table.nMask = 0x1F;
|
||||
m_ReflCop0Table.pTable = m_ReflCop0;
|
||||
|
||||
m_ReflBc0Table.nShift = 16;
|
||||
m_ReflBc0Table.nMask = 0x03;
|
||||
m_ReflBc0Table.pTable = m_ReflBc0;
|
||||
|
||||
m_ReflC0Table.nShift = 0;
|
||||
m_ReflC0Table.nMask = 0x3F;
|
||||
m_ReflC0Table.pTable = m_ReflC0;
|
||||
|
||||
m_ReflGeneral[0x10].pSubTable = &m_ReflCop0Table;
|
||||
|
||||
m_ReflCop0[0x08].pSubTable = &m_ReflBc0Table;
|
||||
m_ReflCop0[0x10].pSubTable = &m_ReflC0Table;
|
||||
}
|
||||
|
||||
void CCOP_SCU::GetInstruction(uint32 nOpcode, char* sText)
|
||||
{
|
||||
unsigned int nCount = 256;
|
||||
if(nOpcode == 0)
|
||||
{
|
||||
strncpy(sText, "NOP", nCount);
|
||||
return;
|
||||
}
|
||||
|
||||
INSTRUCTION Instr;
|
||||
Instr.pGetMnemonic = SubTableMnemonic;
|
||||
Instr.pSubTable = &m_ReflGeneralTable;
|
||||
Instr.pGetMnemonic(&Instr, NULL, nOpcode, sText, nCount);
|
||||
}
|
||||
|
||||
void CCOP_SCU::GetArguments(uint32 nAddress, uint32 nOpcode, char* sText)
|
||||
{
|
||||
unsigned int nCount = 256;
|
||||
if(nOpcode == 0)
|
||||
{
|
||||
strncpy(sText, "", nCount);
|
||||
return;
|
||||
}
|
||||
|
||||
INSTRUCTION Instr;
|
||||
Instr.pGetOperands = SubTableOperands;
|
||||
Instr.pSubTable = &m_ReflGeneralTable;
|
||||
Instr.pGetOperands(&Instr, NULL, nAddress, nOpcode, sText, nCount);
|
||||
}
|
||||
|
||||
MIPS_BRANCH_TYPE CCOP_SCU::IsBranch(uint32 nOpcode)
|
||||
{
|
||||
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
||||
|
||||
INSTRUCTION Instr;
|
||||
Instr.pIsBranch = SubTableIsBranch;
|
||||
Instr.pSubTable = &m_ReflGeneralTable;
|
||||
return Instr.pIsBranch(&Instr, NULL, nOpcode);
|
||||
}
|
||||
|
||||
uint32 CCOP_SCU::GetEffectiveAddress(uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
if(nOpcode == 0) return 0;
|
||||
|
||||
INSTRUCTION Instr;
|
||||
Instr.pGetEffectiveAddress = SubTableEffAddr;
|
||||
Instr.pSubTable = &m_ReflGeneralTable;
|
||||
return Instr.pGetEffectiveAddress(&Instr, NULL, nAddress, nOpcode);
|
||||
}
|
@ -13,7 +13,7 @@ public:
|
||||
virtual void GetInstruction(uint32, char*);
|
||||
virtual void GetArguments(uint32, uint32, char*);
|
||||
virtual uint32 GetEffectiveAddress(uint32, uint32);
|
||||
virtual bool IsBranch(uint32);
|
||||
virtual MIPS_BRANCH_TYPE IsBranch(uint32);
|
||||
|
||||
protected:
|
||||
typedef void (CCOP_VU::*InstructionFuncConstant)();
|
||||
|
@ -245,7 +245,7 @@ INSTRUCTION CCOP_VU::m_cReflV[64] =
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x38
|
||||
{ "VCALLMS", NULL, CopyMnemonic, ReflOpImm15, NULL, NULL },
|
||||
{ "VCALLMS", NULL, CopyMnemonic, ReflOpImm15, IsNoDelayBranch, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
@ -510,9 +510,9 @@ void CCOP_VU::GetArguments(uint32 nAddress, uint32 nOpcode, char* sText)
|
||||
Instr.pGetOperands(&Instr, pCtx, nAddress, nOpcode, sText, 256);
|
||||
}
|
||||
|
||||
bool CCOP_VU::IsBranch(uint32 nOpcode)
|
||||
MIPS_BRANCH_TYPE CCOP_VU::IsBranch(uint32 nOpcode)
|
||||
{
|
||||
if(nOpcode == 0) return false;
|
||||
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
||||
|
||||
CMIPS* pCtx = NULL;
|
||||
|
||||
|
@ -13,7 +13,7 @@ public:
|
||||
virtual void CompileInstruction(uint32, CMipsJitter*, 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 MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32);
|
||||
virtual uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32);
|
||||
|
||||
protected:
|
||||
@ -53,7 +53,7 @@ protected:
|
||||
|
||||
static void ReflCOPMnemonic(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||
static void ReflCOPOperands(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
static bool ReflCOPIsBranch(MIPSReflection::INSTRUCTION*, CMIPS*, uint32);
|
||||
static MIPS_BRANCH_TYPE ReflCOPIsBranch(MIPSReflection::INSTRUCTION*, CMIPS*, uint32);
|
||||
static uint32 ReflCOPEffeAddr(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||
|
||||
MIPSReflection::INSTRUCTION m_ReflGeneral[MAX_GENERAL_OPS];
|
||||
|
@ -185,8 +185,7 @@ uint32 CMA_MIPSIV::ReflEaOffset(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddres
|
||||
|
||||
void CMA_MIPSIV::ReflCOPMnemonic(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
unsigned int nCOP;
|
||||
nCOP = *(unsigned int*)&pInstr->pSubTable;
|
||||
unsigned int nCOP = *(unsigned int*)&pInstr->pSubTable;
|
||||
if(pCtx->m_pCOP[nCOP] != NULL)
|
||||
{
|
||||
pCtx->m_pCOP[nCOP]->GetInstruction(nOpcode, sText);
|
||||
@ -199,8 +198,7 @@ void CMA_MIPSIV::ReflCOPMnemonic(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcod
|
||||
|
||||
void CMA_MIPSIV::ReflCOPOperands(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||
{
|
||||
unsigned int nCOP;
|
||||
nCOP = *(unsigned int*)&pInstr->pSubTable;
|
||||
unsigned int nCOP = *(unsigned int*)&pInstr->pSubTable;
|
||||
if(pCtx->m_pCOP[nCOP] != NULL)
|
||||
{
|
||||
pCtx->m_pCOP[nCOP]->GetArguments(nAddress, nOpcode, sText);
|
||||
@ -211,24 +209,22 @@ void CMA_MIPSIV::ReflCOPOperands(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddre
|
||||
}
|
||||
}
|
||||
|
||||
bool CMA_MIPSIV::ReflCOPIsBranch(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode)
|
||||
MIPS_BRANCH_TYPE CMA_MIPSIV::ReflCOPIsBranch(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode)
|
||||
{
|
||||
unsigned int nCOP;
|
||||
nCOP = *(unsigned int*)&pInstr->pSubTable;
|
||||
unsigned int nCOP = *(unsigned int*)&pInstr->pSubTable;
|
||||
if(pCtx->m_pCOP[nCOP] != NULL)
|
||||
{
|
||||
return pCtx->m_pCOP[nCOP]->IsBranch(nOpcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
return MIPS_BRANCH_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CMA_MIPSIV::ReflCOPEffeAddr(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
unsigned int nCOP;
|
||||
nCOP = *(unsigned int*)&pInstr->pSubTable;
|
||||
unsigned int nCOP = *(unsigned int*)&pInstr->pSubTable;
|
||||
if(pCtx->m_pCOP[nCOP] != NULL)
|
||||
{
|
||||
return pCtx->m_pCOP[nCOP]->GetEffectiveAddress(nAddress, nOpcode);
|
||||
@ -331,7 +327,7 @@ INSTRUCTION CMA_MIPSIV::m_cReflSpecial[64] =
|
||||
{ "JALR", NULL, CopyMnemonic, ReflOpRdRs, IsBranch, NULL },
|
||||
{ "MOVZ", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ "MOVN", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ "SYSCALL", NULL, CopyMnemonic, NULL, NULL, NULL },
|
||||
{ "SYSCALL", NULL, CopyMnemonic, NULL, IsNoDelayBranch, NULL },
|
||||
{ "BREAK", NULL, CopyMnemonic, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ "SYNC", NULL, CopyMnemonic, NULL, NULL, NULL },
|
||||
@ -487,11 +483,11 @@ void CMA_MIPSIV::GetInstructionOperands(CMIPS* pCtx, uint32 nAddress, uint32 nOp
|
||||
Instr.pGetOperands(&Instr, pCtx, nAddress, nOpcode, sText, nCount);
|
||||
}
|
||||
|
||||
bool CMA_MIPSIV::IsInstructionBranch(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
MIPS_BRANCH_TYPE CMA_MIPSIV::IsInstructionBranch(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
INSTRUCTION Instr;
|
||||
|
||||
if(nOpcode == 0) return false;
|
||||
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
||||
|
||||
Instr.pIsBranch = SubTableIsBranch;
|
||||
Instr.pSubTable = &m_ReflGeneralTable;
|
||||
|
@ -57,7 +57,7 @@ void CMA_VU::GetInstructionOperands(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode
|
||||
}
|
||||
}
|
||||
|
||||
bool CMA_VU::IsInstructionBranch(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
MIPS_BRANCH_TYPE CMA_VU::IsInstructionBranch(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
if(nAddress & 0x04)
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
virtual void CompileInstruction(uint32, CMipsJitter*, 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 MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32);
|
||||
virtual uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32);
|
||||
VUShared::OPERANDSET GetAffectedOperands(CMIPS*, uint32, uint32);
|
||||
|
||||
@ -33,7 +33,7 @@ private:
|
||||
void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
VUShared::OPERANDSET GetAffectedOperands(CMIPS*, uint32, uint32);
|
||||
bool IsInstructionBranch(CMIPS*, uint32, uint32);
|
||||
MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32);
|
||||
uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32);
|
||||
|
||||
private:
|
||||
@ -161,7 +161,7 @@ private:
|
||||
void CompileInstruction(uint32, CMipsJitter*, CMIPS*);
|
||||
void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
bool IsInstructionBranch(CMIPS*, uint32, uint32);
|
||||
MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32);
|
||||
uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32);
|
||||
VUShared::OPERANDSET GetAffectedOperands(CMIPS*, uint32, uint32);
|
||||
|
||||
|
@ -1230,13 +1230,13 @@ void CMA_VU::CLower::GetInstructionOperands(CMIPS* pCtx, uint32 nAddress, uint32
|
||||
Instr.pGetOperands(&Instr, pCtx, nAddress, nOpcode, sText, nCount);
|
||||
}
|
||||
|
||||
bool CMA_VU::CLower::IsInstructionBranch(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
MIPS_BRANCH_TYPE CMA_VU::CLower::IsInstructionBranch(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
INSTRUCTION Instr;
|
||||
|
||||
if(nOpcode == 0x8000033C)
|
||||
{
|
||||
return false;
|
||||
return MIPS_BRANCH_NONE;
|
||||
}
|
||||
|
||||
Instr.pIsBranch = SubTableIsBranch;
|
||||
|
@ -593,7 +593,7 @@ void CMA_VU::CUpper::GetInstructionOperands(CMIPS* pCtx, uint32 nAddress, uint32
|
||||
Instr.pGetOperands(&Instr, pCtx, nAddress, nOpcode, sText, nCount);
|
||||
}
|
||||
|
||||
bool CMA_VU::CUpper::IsInstructionBranch(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
MIPS_BRANCH_TYPE CMA_VU::CUpper::IsInstructionBranch(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||
{
|
||||
INSTRUCTION Instr;
|
||||
|
||||
|
@ -76,9 +76,8 @@ long CMIPS::GetBranch(uint16 nData)
|
||||
|
||||
bool CMIPS::IsBranch(uint32 nAddress)
|
||||
{
|
||||
uint32 nOpcode;
|
||||
nOpcode = m_pMemoryMap->GetInstruction(nAddress);
|
||||
return m_pArch->IsInstructionBranch(this, nAddress, nOpcode);
|
||||
uint32 nOpcode = m_pMemoryMap->GetInstruction(nAddress);
|
||||
return m_pArch->IsInstructionBranch(this, nAddress, nOpcode) == MIPS_BRANCH_NORMAL;
|
||||
}
|
||||
|
||||
uint32 CMIPS::TranslateAddress64(CMIPS* pC, uint32 nVAddrHI, uint32 nVAddrLO)
|
||||
|
@ -6,12 +6,12 @@
|
||||
class CMIPSArchitecture : public CMIPSInstructionFactory
|
||||
{
|
||||
public:
|
||||
CMIPSArchitecture(MIPS_REGSIZE);
|
||||
virtual ~CMIPSArchitecture();
|
||||
virtual void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int) = 0;
|
||||
virtual void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int) = 0;
|
||||
virtual bool IsInstructionBranch(CMIPS*, uint32, uint32) = 0;
|
||||
virtual uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32) = 0;
|
||||
CMIPSArchitecture(MIPS_REGSIZE);
|
||||
virtual ~CMIPSArchitecture();
|
||||
virtual void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int) = 0;
|
||||
virtual void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int) = 0;
|
||||
virtual MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32) = 0;
|
||||
virtual uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -6,12 +6,12 @@
|
||||
class CMIPSCoprocessor : public CMIPSInstructionFactory
|
||||
{
|
||||
public:
|
||||
CMIPSCoprocessor(MIPS_REGSIZE);
|
||||
virtual ~CMIPSCoprocessor();
|
||||
virtual void GetInstruction(uint32, char*) = 0;
|
||||
virtual void GetArguments(uint32, uint32, char*) = 0;
|
||||
virtual uint32 GetEffectiveAddress(uint32, uint32) = 0;
|
||||
virtual bool IsBranch(uint32) = 0;
|
||||
CMIPSCoprocessor(MIPS_REGSIZE);
|
||||
virtual ~CMIPSCoprocessor();
|
||||
virtual void GetInstruction(uint32, char*) = 0;
|
||||
virtual void GetArguments(uint32, uint32, char*) = 0;
|
||||
virtual uint32 GetEffectiveAddress(uint32, uint32) = 0;
|
||||
virtual MIPS_BRANCH_TYPE IsBranch(uint32) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,13 @@ enum MIPS_REGSIZE
|
||||
MIPS_REGSIZE_64 = 1,
|
||||
};
|
||||
|
||||
enum MIPS_BRANCH_TYPE
|
||||
{
|
||||
MIPS_BRANCH_NONE = 0,
|
||||
MIPS_BRANCH_NORMAL = 1,
|
||||
MIPS_BRANCH_NODELAY = 2,
|
||||
};
|
||||
|
||||
class CMIPSInstructionFactory
|
||||
{
|
||||
public:
|
||||
|
@ -39,17 +39,22 @@ void MIPSReflection::SubTableOperands(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 n
|
||||
pInstr->pGetOperands(pInstr, pCtx, nAddress, nOpcode, sText, nCount);
|
||||
}
|
||||
|
||||
bool MIPSReflection::IsBranch(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode)
|
||||
MIPS_BRANCH_TYPE MIPSReflection::IsBranch(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode)
|
||||
{
|
||||
return true;
|
||||
return MIPS_BRANCH_NORMAL;
|
||||
}
|
||||
|
||||
bool MIPSReflection::SubTableIsBranch(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode)
|
||||
MIPS_BRANCH_TYPE MIPSReflection::IsNoDelayBranch(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode)
|
||||
{
|
||||
return MIPS_BRANCH_NODELAY;
|
||||
}
|
||||
|
||||
MIPS_BRANCH_TYPE MIPSReflection::SubTableIsBranch(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode)
|
||||
{
|
||||
pInstr = DereferenceInstruction(pInstr->pSubTable, nOpcode);
|
||||
if(pInstr->pIsBranch == NULL)
|
||||
{
|
||||
return false;
|
||||
return MIPS_BRANCH_NONE;
|
||||
}
|
||||
return pInstr->pIsBranch(pInstr, pCtx, nOpcode);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _MIPSREFLECTION_H_
|
||||
|
||||
#include "Types.h"
|
||||
#include "MIPSArchitecture.h"
|
||||
|
||||
class CMIPS;
|
||||
|
||||
@ -18,25 +19,26 @@ namespace MIPSReflection
|
||||
|
||||
struct INSTRUCTION
|
||||
{
|
||||
const char* sMnemonic;
|
||||
SUBTABLE* pSubTable;
|
||||
void (*pGetMnemonic)(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||
void (*pGetOperands)(INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
bool (*pIsBranch)(INSTRUCTION*, CMIPS*, uint32);
|
||||
uint32 (*pGetEffectiveAddress)(INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||
const char* sMnemonic;
|
||||
SUBTABLE* pSubTable;
|
||||
void (*pGetMnemonic)(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||
void (*pGetOperands)(INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
MIPS_BRANCH_TYPE (*pIsBranch)(INSTRUCTION*, CMIPS*, uint32);
|
||||
uint32 (*pGetEffectiveAddress)(INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||
};
|
||||
|
||||
INSTRUCTION* DereferenceInstruction(SUBTABLE*, uint32);
|
||||
INSTRUCTION* DereferenceInstruction(SUBTABLE*, uint32);
|
||||
|
||||
void CopyMnemonic(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||
void SubTableMnemonic(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||
void CopyMnemonic(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||
void SubTableMnemonic(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||
|
||||
void SubTableOperands(INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
void SubTableOperands(INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||
|
||||
bool IsBranch(INSTRUCTION*, CMIPS*, uint32);
|
||||
bool SubTableIsBranch(INSTRUCTION*, CMIPS*, uint32);
|
||||
MIPS_BRANCH_TYPE IsBranch(INSTRUCTION*, CMIPS*, uint32);
|
||||
MIPS_BRANCH_TYPE IsNoDelayBranch(INSTRUCTION*, CMIPS*, uint32);
|
||||
MIPS_BRANCH_TYPE SubTableIsBranch(INSTRUCTION*, CMIPS*, uint32);
|
||||
|
||||
uint32 SubTableEffAddr(INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||
uint32 SubTableEffAddr(INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -268,8 +268,8 @@ void CMipsExecutor::PartitionFunction(uint32 functionAddress)
|
||||
for(uint32 address = functionAddress; address <= endAddress; address += 4)
|
||||
{
|
||||
uint32 opcode = m_context.m_pMemoryMap->GetInstruction(address);
|
||||
bool isBranch = m_context.m_pArch->IsInstructionBranch(&m_context, address, opcode);
|
||||
if(isBranch)
|
||||
MIPS_BRANCH_TYPE branchType = m_context.m_pArch->IsInstructionBranch(&m_context, address, opcode);
|
||||
if(branchType == MIPS_BRANCH_NORMAL)
|
||||
{
|
||||
partitionPoints.insert(address + 8);
|
||||
uint32 target = m_context.m_pArch->GetInstructionEffectiveAddress(&m_context, address, opcode);
|
||||
@ -278,11 +278,10 @@ void CMipsExecutor::PartitionFunction(uint32 functionAddress)
|
||||
partitionPoints.insert(target);
|
||||
}
|
||||
}
|
||||
//SYSCALL or ERET
|
||||
if(opcode == 0x0000000C || opcode == 0x42000018)
|
||||
{
|
||||
partitionPoints.insert(address + 4);
|
||||
}
|
||||
else if(branchType == MIPS_BRANCH_NODELAY)
|
||||
{
|
||||
partitionPoints.insert(address + 4);
|
||||
}
|
||||
//Check if there's a block already exising that this address
|
||||
if(address != endAddress)
|
||||
{
|
||||
@ -297,14 +296,40 @@ void CMipsExecutor::PartitionFunction(uint32 functionAddress)
|
||||
}
|
||||
}
|
||||
|
||||
uint32 currentPoint = -1;
|
||||
for(PartitionPointSet::const_iterator pointIterator(partitionPoints.begin());
|
||||
pointIterator != partitionPoints.end(); pointIterator++)
|
||||
{
|
||||
if(currentPoint != -1)
|
||||
{
|
||||
CreateBlock(currentPoint, *pointIterator - 4);
|
||||
}
|
||||
currentPoint = *pointIterator;
|
||||
}
|
||||
//Check if blocks are too big
|
||||
{
|
||||
uint32 currentPoint = -1;
|
||||
for(PartitionPointSet::const_iterator pointIterator(partitionPoints.begin());
|
||||
pointIterator != partitionPoints.end(); pointIterator++)
|
||||
{
|
||||
if(currentPoint != -1)
|
||||
{
|
||||
uint32 startPos = currentPoint;
|
||||
uint32 endPos = *pointIterator;
|
||||
uint32 distance = (endPos - startPos);
|
||||
if(distance > 0x400)
|
||||
{
|
||||
uint32 middlePos = ((endPos + startPos) / 2) & ~0x03;
|
||||
pointIterator = partitionPoints.insert(middlePos).first;
|
||||
pointIterator--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
currentPoint = *pointIterator;
|
||||
}
|
||||
}
|
||||
|
||||
//Create blocks
|
||||
{
|
||||
uint32 currentPoint = -1;
|
||||
for(PartitionPointSet::const_iterator pointIterator(partitionPoints.begin());
|
||||
pointIterator != partitionPoints.end(); pointIterator++)
|
||||
{
|
||||
if(currentPoint != -1)
|
||||
{
|
||||
CreateBlock(currentPoint, *pointIterator - 4);
|
||||
}
|
||||
currentPoint = *pointIterator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,8 +95,8 @@ void CVuExecutor::PartitionFunction(uint32 functionAddress)
|
||||
for(uint32 address = functionAddress; address <= endAddress; address += 4)
|
||||
{
|
||||
uint32 opcode = m_context.m_pMemoryMap->GetInstruction(address);
|
||||
bool isBranch = m_context.m_pArch->IsInstructionBranch(&m_context, address, opcode);
|
||||
if(isBranch)
|
||||
MIPS_BRANCH_TYPE branchType = m_context.m_pArch->IsInstructionBranch(&m_context, address, opcode);
|
||||
if(branchType == MIPS_BRANCH_NORMAL)
|
||||
{
|
||||
assert((address & 0x07) == 0x00);
|
||||
partitionPoints.insert(address + 0x10);
|
||||
@ -107,12 +107,7 @@ void CVuExecutor::PartitionFunction(uint32 functionAddress)
|
||||
partitionPoints.insert(target);
|
||||
}
|
||||
}
|
||||
//-- Meaningless in VU
|
||||
//SYSCALL or ERET
|
||||
//if(opcode == 0x0000000C || opcode == 0x42000018)
|
||||
//{
|
||||
// partitionPoints.insert(address + 4);
|
||||
//}
|
||||
|
||||
//Check if there's a block already exising that this address
|
||||
if(address != endAddress)
|
||||
{
|
||||
|
@ -168,7 +168,7 @@ void CDisAsm::GotoEA()
|
||||
return;
|
||||
}
|
||||
nOpcode = GetInstruction(m_nSelected);
|
||||
if(m_pCtx->m_pArch->IsInstructionBranch(m_pCtx, m_nSelected, nOpcode))
|
||||
if(m_pCtx->m_pArch->IsInstructionBranch(m_pCtx, m_nSelected, nOpcode) == MIPS_BRANCH_NORMAL)
|
||||
{
|
||||
nAddress = m_pCtx->m_pArch->GetInstructionEffectiveAddress(m_pCtx, m_nSelected, nOpcode);
|
||||
|
||||
@ -466,7 +466,7 @@ long CDisAsm::OnRightButtonUp(int nX, int nY)
|
||||
if(m_nSelected != MIPS_INVALID_PC)
|
||||
{
|
||||
nOpcode = GetInstruction(m_nSelected);
|
||||
if(m_pCtx->m_pArch->IsInstructionBranch(m_pCtx, m_nSelected, nOpcode))
|
||||
if(m_pCtx->m_pArch->IsInstructionBranch(m_pCtx, m_nSelected, nOpcode) == MIPS_BRANCH_NORMAL)
|
||||
{
|
||||
nAddress = m_pCtx->m_pArch->GetInstructionEffectiveAddress(m_pCtx, m_nSelected, nOpcode);
|
||||
_sntprintf(sTemp, countof(sTemp), _T("Go to 0x%0.8X"), nAddress);
|
||||
@ -829,7 +829,7 @@ void CDisAsm::Paint(HDC hDC)
|
||||
|
||||
if(!nCommentDrawn)
|
||||
{
|
||||
if(m_pCtx->m_pArch->IsInstructionBranch(m_pCtx, nAddress, nData))
|
||||
if(m_pCtx->m_pArch->IsInstructionBranch(m_pCtx, nAddress, nData) == MIPS_BRANCH_NORMAL)
|
||||
{
|
||||
nEffAddr = m_pCtx->m_pArch->GetInstructionEffectiveAddress(m_pCtx, nAddress, nData);
|
||||
sTag = m_pCtx->m_Functions.Find(nEffAddr);
|
||||
|
Loading…
Reference in New Issue
Block a user