2007-12-07 00:26:56 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
#include "MA_EE.h"
|
|
|
|
#include "MIPS.h"
|
2008-04-09 02:52:38 +00:00
|
|
|
#include "CodeGen.h"
|
2007-12-07 00:26:56 +00:00
|
|
|
#include "PS2OS.h"
|
|
|
|
#include "offsetof_def.h"
|
2008-04-09 02:52:38 +00:00
|
|
|
#include "MemoryUtils.h"
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-17 04:59:27 +00:00
|
|
|
using namespace std;
|
2008-01-02 04:03:05 +00:00
|
|
|
using namespace std::tr1;
|
2007-12-07 00:26:56 +00:00
|
|
|
|
|
|
|
CMA_EE g_MAEE;
|
|
|
|
|
|
|
|
CMA_EE::CMA_EE() :
|
|
|
|
CMA_MIPSIV(MIPS_REGSIZE_64)
|
|
|
|
{
|
|
|
|
m_pOpGeneral[0x1E] = LQ;
|
|
|
|
m_pOpGeneral[0x1F] = SQ;
|
|
|
|
|
|
|
|
//OS special instructions
|
|
|
|
m_pOpSpecial[0x1D] = REEXCPT;
|
|
|
|
|
|
|
|
m_pOpRegImm[0x18] = MTSAB;
|
|
|
|
m_pOpRegImm[0x19] = MTSAH;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
SetupReflectionTables();
|
|
|
|
}
|
|
|
|
|
|
|
|
CMA_EE::~CMA_EE()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMA_EE::PushVector(unsigned int nReg)
|
|
|
|
{
|
2008-01-12 07:00:48 +00:00
|
|
|
m_codeGen->MD_PushRel(offsetof(CMIPS, m_State.nGPR[nReg]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMA_EE::PullVector(unsigned int nReg)
|
|
|
|
{
|
2008-01-12 07:00:48 +00:00
|
|
|
m_codeGen->MD_PullRel(offsetof(CMIPS, m_State.nGPR[nReg]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//General Opcodes
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//1E
|
|
|
|
void CMA_EE::LQ()
|
|
|
|
{
|
2008-04-09 02:52:38 +00:00
|
|
|
ComputeMemAccessAddr();
|
2008-01-07 04:05:17 +00:00
|
|
|
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
m_codeGen->PushRef(m_pCtx);
|
|
|
|
m_codeGen->PushIdx(1);
|
2008-04-09 02:52:38 +00:00
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&CMemoryUtils::GetWordProxy), 2, true);
|
2008-01-07 04:05:17 +00:00
|
|
|
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[i]));
|
|
|
|
|
|
|
|
if(i != 3)
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(4);
|
|
|
|
m_codeGen->Add();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_codeGen->PullTop();
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1F
|
|
|
|
void CMA_EE::SQ()
|
|
|
|
{
|
2008-04-09 02:52:38 +00:00
|
|
|
ComputeMemAccessAddr();
|
2007-12-07 00:26:56 +00:00
|
|
|
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
m_codeGen->PushRef(m_pCtx);
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[i]));
|
|
|
|
m_codeGen->PushIdx(2);
|
2008-04-09 02:52:38 +00:00
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&CMemoryUtils::SetWordProxy), 3, false);
|
2007-12-07 00:26:56 +00:00
|
|
|
|
|
|
|
if(i != 3)
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(4);
|
|
|
|
m_codeGen->Add();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_codeGen->PullTop();
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//RegImm Opcodes
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//18
|
|
|
|
void CMA_EE::MTSAB()
|
|
|
|
{
|
2008-02-08 22:07:28 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
|
|
|
|
m_codeGen->PushCst(0x0F);
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->PushCst(m_nImmediate & 0x0F);
|
|
|
|
m_codeGen->Xor();
|
|
|
|
m_codeGen->Shl(0x03);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nSA));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//19
|
|
|
|
void CMA_EE::MTSAH()
|
|
|
|
{
|
2008-01-19 03:36:27 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
|
|
|
|
m_codeGen->PushCst(0x07);
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->PushCst(m_nImmediate & 0x07);
|
|
|
|
m_codeGen->Xor();
|
|
|
|
m_codeGen->Shl(0x04);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nSA));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//Special Opcodes
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void CMA_EE::REEXCPT()
|
|
|
|
{
|
|
|
|
// m_pB->Call(CPS2OS::ExceptionReentry, 0, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//MMI Opcodes
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//00
|
|
|
|
void CMA_EE::MADD()
|
|
|
|
{
|
2008-01-17 04:59:27 +00:00
|
|
|
//prod = (HI || LO) + (RS * RT)
|
|
|
|
//LO = sex(prod[0])
|
|
|
|
//HI = sex(prod[1])
|
|
|
|
//RD = LO
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-17 04:59:27 +00:00
|
|
|
size_t lo[2];
|
|
|
|
size_t hi[2];
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-17 04:59:27 +00:00
|
|
|
unsigned int unit = 0;
|
|
|
|
switch(unit)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
lo[0] = offsetof(CMIPS, m_State.nLO[0]);
|
|
|
|
lo[1] = offsetof(CMIPS, m_State.nLO[1]);
|
|
|
|
hi[0] = offsetof(CMIPS, m_State.nHI[0]);
|
|
|
|
hi[1] = offsetof(CMIPS, m_State.nHI[1]);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
lo[0] = offsetof(CMIPS, m_State.nLO1[0]);
|
|
|
|
lo[1] = offsetof(CMIPS, m_State.nLO1[1]);
|
|
|
|
hi[0] = offsetof(CMIPS, m_State.nHI1[0]);
|
|
|
|
hi[1] = offsetof(CMIPS, m_State.nHI1[1]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw runtime_error("Invalid unit number.");
|
|
|
|
break;
|
|
|
|
}
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-17 04:59:27 +00:00
|
|
|
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->MultS(); //gives Stack(0) = LO, Stack(1) = HI
|
|
|
|
m_codeGen->Swap();
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-17 04:59:27 +00:00
|
|
|
m_codeGen->PushRel(lo[0]);
|
|
|
|
m_codeGen->PushRel(hi[0]);
|
|
|
|
m_codeGen->Add64();
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-17 04:59:27 +00:00
|
|
|
m_codeGen->SeX();
|
|
|
|
m_codeGen->PullRel(hi[1]);
|
|
|
|
m_codeGen->PullRel(hi[0]);
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-17 04:59:27 +00:00
|
|
|
m_codeGen->SeX();
|
|
|
|
m_codeGen->PullRel(lo[1]);
|
|
|
|
m_codeGen->PullRel(lo[0]);
|
|
|
|
|
|
|
|
if(m_nRD != 0)
|
|
|
|
{
|
|
|
|
m_codeGen->PushRel(lo[0]);
|
|
|
|
m_codeGen->PushRel(lo[1]);
|
|
|
|
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
|
|
|
|
}
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//04
|
|
|
|
void CMA_EE::PLZCW()
|
|
|
|
{
|
2008-04-07 00:51:28 +00:00
|
|
|
for(unsigned int i = 0; i < 2; i++)
|
|
|
|
{
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[i]));
|
|
|
|
m_codeGen->Lzc();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[i]));
|
|
|
|
}
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//08
|
|
|
|
void CMA_EE::MMI0()
|
|
|
|
{
|
|
|
|
m_pOpMmi0[(m_nOpcode >> 6) & 0x1F]();
|
|
|
|
}
|
|
|
|
|
|
|
|
//09
|
|
|
|
void CMA_EE::MMI2()
|
|
|
|
{
|
|
|
|
m_pOpMmi2[(m_nOpcode >> 6) & 0x1F]();
|
|
|
|
}
|
|
|
|
|
|
|
|
//10
|
|
|
|
void CMA_EE::MFHI1()
|
|
|
|
{
|
2008-01-12 01:27:04 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nHI1[0]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-12 01:27:04 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nHI1[1]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//11
|
|
|
|
void CMA_EE::MTHI1()
|
|
|
|
{
|
2008-01-19 03:36:27 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHI1[0]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-19 03:36:27 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHI1[1]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//12
|
|
|
|
void CMA_EE::MFLO1()
|
|
|
|
{
|
2008-01-12 01:27:04 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nLO1[0]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-12 01:27:04 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nLO1[1]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//13
|
|
|
|
void CMA_EE::MTLO1()
|
|
|
|
{
|
2008-01-19 03:36:27 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nLO1[0]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-19 03:36:27 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nLO1[1]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//18
|
|
|
|
void CMA_EE::MULT1()
|
|
|
|
{
|
2008-01-02 04:03:05 +00:00
|
|
|
Template_Mult32()(bind(&CCodeGen::MultS, m_codeGen), 1);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//19
|
|
|
|
void CMA_EE::MULTU1()
|
|
|
|
{
|
2008-01-12 01:27:04 +00:00
|
|
|
Template_Mult32()(bind(&CCodeGen::Mult, m_codeGen), 1);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1A
|
|
|
|
void CMA_EE::DIV1()
|
|
|
|
{
|
2008-01-15 20:27:44 +00:00
|
|
|
Template_Div32()(bind(&CCodeGen::DivS, m_codeGen), 1);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1B
|
|
|
|
void CMA_EE::DIVU1()
|
|
|
|
{
|
2008-01-15 20:27:44 +00:00
|
|
|
Template_Div32()(bind(&CCodeGen::Div, m_codeGen), 1);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//28
|
|
|
|
void CMA_EE::MMI1()
|
|
|
|
{
|
|
|
|
m_pOpMmi1[(m_nOpcode >> 6) & 0x1F]();
|
|
|
|
}
|
|
|
|
|
|
|
|
//29
|
|
|
|
void CMA_EE::MMI3()
|
|
|
|
{
|
|
|
|
m_pOpMmi3[(m_nOpcode >> 6) & 0x1F]();
|
|
|
|
}
|
|
|
|
|
|
|
|
//34
|
|
|
|
void CMA_EE::PSLLH()
|
|
|
|
{
|
2008-02-10 23:08:04 +00:00
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_SllH(m_nSA);
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//36
|
|
|
|
void CMA_EE::PSRLH()
|
|
|
|
{
|
2008-02-08 22:07:28 +00:00
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_SrlH(m_nSA);
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//37
|
|
|
|
void CMA_EE::PSRAH()
|
|
|
|
{
|
2008-02-10 23:08:04 +00:00
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_SraH(m_nSA);
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//MMI0 Opcodes
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//01
|
|
|
|
void CMA_EE::PSUBW()
|
|
|
|
{
|
2008-01-15 20:27:44 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_SubW();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//04
|
|
|
|
void CMA_EE::PADDH()
|
|
|
|
{
|
2008-02-08 22:07:28 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_AddH();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//06
|
|
|
|
void CMA_EE::PCGTH()
|
|
|
|
{
|
2008-02-08 22:07:28 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_CmpGtH();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//07
|
|
|
|
void CMA_EE::PMAXH()
|
|
|
|
{
|
2008-02-01 02:34:50 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_MaxH();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//09
|
|
|
|
void CMA_EE::PSUBB()
|
|
|
|
{
|
2008-01-12 07:00:48 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_SubB();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//10
|
|
|
|
void CMA_EE::PADDSW()
|
|
|
|
{
|
2008-03-08 15:51:03 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_AddWSS();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//12
|
|
|
|
void CMA_EE::PEXTLW()
|
|
|
|
{
|
2008-02-29 02:11:27 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_UnpackLowerWD();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//16
|
|
|
|
void CMA_EE::PEXTLH()
|
|
|
|
{
|
2008-02-27 02:23:28 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_UnpackLowerHW();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//17
|
|
|
|
void CMA_EE::PPACH()
|
|
|
|
{
|
2008-03-16 22:31:37 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_PackWH();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1A
|
|
|
|
void CMA_EE::PEXTLB()
|
|
|
|
{
|
2008-02-08 22:07:28 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_UnpackLowerBH();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1B
|
|
|
|
void CMA_EE::PPACB()
|
|
|
|
{
|
2008-02-01 02:34:50 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_PackHB();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1E
|
|
|
|
void CMA_EE::PEXT5()
|
|
|
|
{
|
2008-02-27 02:23:28 +00:00
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-02-27 02:23:28 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[i]));
|
|
|
|
m_codeGen->PushCst(0x001F);
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->Shl(3);
|
|
|
|
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[i]));
|
|
|
|
m_codeGen->PushCst(0x03E0);
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->Shl(6);
|
|
|
|
m_codeGen->Or();
|
|
|
|
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[i]));
|
|
|
|
m_codeGen->PushCst(0x7C00);
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->Shl(9);
|
|
|
|
m_codeGen->Or();
|
|
|
|
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[i]));
|
|
|
|
m_codeGen->PushCst(0x8000);
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->Shl(16);
|
|
|
|
m_codeGen->Or();
|
|
|
|
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[i]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//MMI1 Opcodes
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//02
|
|
|
|
void CMA_EE::PCEQW()
|
|
|
|
{
|
2008-03-16 22:31:37 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_CmpEqW();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//07
|
|
|
|
void CMA_EE::PMINH()
|
|
|
|
{
|
2008-02-01 02:34:50 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_MinH();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//10
|
|
|
|
void CMA_EE::PADDUW()
|
|
|
|
{
|
2008-01-19 03:36:27 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_AddWUS();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//12
|
|
|
|
void CMA_EE::PEXTUW()
|
|
|
|
{
|
2008-02-29 02:11:27 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_UnpackUpperWD();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1A
|
|
|
|
void CMA_EE::PEXTUB()
|
|
|
|
{
|
2008-02-08 22:07:28 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_UnpackUpperBH();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1B
|
|
|
|
void CMA_EE::QFSRV()
|
|
|
|
{
|
2008-02-08 22:07:28 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nSA));
|
|
|
|
m_codeGen->MD_Srl256();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//MMI2 Opcodes
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//0E
|
|
|
|
void CMA_EE::PCPYLD()
|
|
|
|
{
|
|
|
|
//A0
|
2008-01-12 01:27:04 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-12 01:27:04 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[3]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[2]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
|
|
|
//B0
|
2008-01-12 01:27:04 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[1]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-12 01:27:04 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//12
|
|
|
|
void CMA_EE::PAND()
|
|
|
|
{
|
2008-01-12 07:00:48 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_And();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//13
|
|
|
|
void CMA_EE::PXOR()
|
|
|
|
{
|
2008-01-15 20:27:44 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_Xor();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//MMI3 Opcodes
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//0E
|
|
|
|
void CMA_EE::PCPYUD()
|
|
|
|
{
|
|
|
|
//A
|
2008-01-12 07:00:48 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[2]));
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[3]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-12 07:00:48 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
|
|
|
//B
|
2008-01-12 07:00:48 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[2]));
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[3]));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-01-12 07:00:48 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[3]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[2]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//12
|
|
|
|
void CMA_EE::POR()
|
|
|
|
{
|
2008-01-21 04:09:08 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_Or();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//13
|
|
|
|
void CMA_EE::PNOR()
|
|
|
|
{
|
2008-01-12 07:00:48 +00:00
|
|
|
PushVector(m_nRS);
|
|
|
|
PushVector(m_nRT);
|
|
|
|
m_codeGen->MD_Or();
|
|
|
|
m_codeGen->MD_Not();
|
|
|
|
PullVector(m_nRD);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1B
|
|
|
|
void CMA_EE::PCPYH()
|
|
|
|
{
|
2008-01-12 01:27:04 +00:00
|
|
|
for(unsigned int i = 0; i < 4; i += 2)
|
|
|
|
{
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[i]));
|
|
|
|
m_codeGen->PushCst(0xFFFF);
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->PushTop();
|
|
|
|
m_codeGen->Shl(16);
|
|
|
|
m_codeGen->Or();
|
|
|
|
m_codeGen->PushTop();
|
|
|
|
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[i + 0]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[i + 1]));
|
|
|
|
}
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//Opcode Tables
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void (*CMA_EE::m_pOpMmi0[0x20])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
Illegal, PSUBW, Illegal, Illegal, PADDH, Illegal, PCGTH, PMAXH,
|
|
|
|
//0x08
|
|
|
|
Illegal, PSUBB, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x10
|
|
|
|
PADDSW, Illegal, PEXTLW, Illegal, Illegal, Illegal, PEXTLH, PPACH,
|
|
|
|
//0x18
|
|
|
|
Illegal, Illegal, PEXTLB, PPACB, Illegal, Illegal, PEXT5, Illegal,
|
|
|
|
};
|
|
|
|
|
|
|
|
void (*CMA_EE::m_pOpMmi1[0x20])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
Illegal, Illegal, PCEQW, Illegal, Illegal, Illegal, Illegal, PMINH,
|
|
|
|
//0x08
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x10
|
|
|
|
PADDUW, Illegal, PEXTUW, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x18
|
|
|
|
Illegal, Illegal, PEXTUB, QFSRV, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
};
|
|
|
|
|
|
|
|
void (*CMA_EE::m_pOpMmi2[0x20])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x08
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, PCPYLD, Illegal,
|
|
|
|
//0x10
|
|
|
|
Illegal, Illegal, PAND, PXOR, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x18
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
};
|
|
|
|
|
|
|
|
void (*CMA_EE::m_pOpMmi3[0x20])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x08
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, PCPYUD, Illegal,
|
|
|
|
//0x10
|
|
|
|
Illegal, Illegal, POR, PNOR, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x18
|
|
|
|
Illegal, Illegal, Illegal, PCPYH, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
};
|