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:
jpd002 2011-12-10 20:49:50 +00:00
parent ab85038514
commit e83a427c11
23 changed files with 519 additions and 303 deletions

View File

@ -396,6 +396,10 @@
RelativePath=".\Source\COP_SCU.h"
>
</File>
<File
RelativePath=".\Source\COP_SCU_Reflection.cpp"
>
</File>
<File
RelativePath=".\Source\ELF.cpp"
>

View File

@ -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();

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View 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);
}

View File

@ -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)();

View File

@ -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;

View File

@ -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];

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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)
{

View File

@ -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);