2006-07-04 22:07:57 +00:00
|
|
|
#include <stddef.h>
|
2006-06-15 04:19:30 +00:00
|
|
|
#include "MA_VU.h"
|
|
|
|
#include "VIF.h"
|
2008-03-22 02:37:01 +00:00
|
|
|
#include "MIPS.h"
|
2006-06-15 04:19:30 +00:00
|
|
|
#include "VUShared.h"
|
|
|
|
#include "CodeGen.h"
|
2007-12-07 00:26:56 +00:00
|
|
|
#include "offsetof_def.h"
|
2008-11-10 01:46:02 +00:00
|
|
|
#include "MemoryUtils.h"
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
using namespace std;
|
2006-06-15 04:19:30 +00:00
|
|
|
|
|
|
|
uint8 CMA_VU::CLower::m_nImm5;
|
|
|
|
uint16 CMA_VU::CLower::m_nImm11;
|
2008-06-17 02:14:22 +00:00
|
|
|
uint16 CMA_VU::CLower::m_nImm12;
|
2006-06-15 04:19:30 +00:00
|
|
|
uint16 CMA_VU::CLower::m_nImm15;
|
|
|
|
uint16 CMA_VU::CLower::m_nImm15S;
|
|
|
|
uint32 CMA_VU::CLower::m_nImm24;
|
|
|
|
uint8 CMA_VU::CLower::m_nIT;
|
|
|
|
uint8 CMA_VU::CLower::m_nIS;
|
|
|
|
uint8 CMA_VU::CLower::m_nID;
|
|
|
|
uint8 CMA_VU::CLower::m_nFSF;
|
|
|
|
uint8 CMA_VU::CLower::m_nFTF;
|
|
|
|
uint8 CMA_VU::CLower::m_nDest;
|
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
CMA_VU::CLower::CLower(bool maskDataAddress) :
|
|
|
|
m_maskDataAddress(maskDataAddress)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
CMA_VU::CLower::~CLower()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-07-20 17:26:08 +00:00
|
|
|
void CMA_VU::CLower::GetQuadWord(uint32 address, CMIPS* ctx, uint32 dstRegister, uint32 dstMask)
|
|
|
|
{
|
|
|
|
assert((address & 0x0F) == 0x00);
|
|
|
|
uint128* destination = &ctx->m_State.nCOP2[dstRegister];
|
|
|
|
CMemoryMap::MEMORYMAPELEMENT* mapElement(ctx->m_pMemoryMap->GetReadMap(address));
|
|
|
|
if((mapElement == NULL) || (mapElement->nType != CMemoryMap::MEMORYMAP_TYPE_MEMORY))
|
|
|
|
{
|
|
|
|
destination->nV0 = 0xCCCCCCCC;
|
|
|
|
destination->nV1 = 0xCCCCCCCC;
|
|
|
|
destination->nV2 = 0xCCCCCCCC;
|
|
|
|
destination->nV3 = 0xCCCCCCCC;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint128* source = reinterpret_cast<uint128*>(&reinterpret_cast<uint8*>(mapElement->pPointer)[address - mapElement->nStart]);
|
|
|
|
if(dstMask == 0xF)
|
|
|
|
{
|
|
|
|
(*destination) = (*source);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if(!VUShared::DestinationHasElement(static_cast<uint8>(dstMask), i)) continue;
|
|
|
|
destination->nV[i] = source->nV[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMA_VU::CLower::SetQuadWord(uint32 address, CMIPS* ctx, uint32 srcRegister, uint32 dstMask)
|
|
|
|
{
|
|
|
|
assert((address & 0x0F) == 0x00);
|
|
|
|
CMemoryMap::MEMORYMAPELEMENT* mapElement(ctx->m_pMemoryMap->GetWriteMap(address));
|
|
|
|
if((mapElement == NULL) || (mapElement->nType != CMemoryMap::MEMORYMAP_TYPE_MEMORY))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint128* source = &ctx->m_State.nCOP2[srcRegister];
|
|
|
|
uint128* destination = reinterpret_cast<uint128*>(&reinterpret_cast<uint8*>(mapElement->pPointer)[address - mapElement->nStart]);
|
|
|
|
if(dstMask == 0xF)
|
|
|
|
{
|
|
|
|
(*destination) = (*source);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if(!VUShared::DestinationHasElement(static_cast<uint8>(dstMask), i)) continue;
|
|
|
|
destination->nV[i] = source->nV[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
void CMA_VU::CLower::ComputeMemAccessAddr(unsigned int baseRegister, uint32 baseOffset, uint32 destOffset)
|
|
|
|
{
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[baseRegister]));
|
|
|
|
if(baseOffset != 0)
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(baseOffset);
|
|
|
|
m_codeGen->Add();
|
|
|
|
}
|
|
|
|
m_codeGen->Shl(4);
|
|
|
|
|
|
|
|
if(destOffset != 0)
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(destOffset);
|
|
|
|
m_codeGen->Add();
|
|
|
|
}
|
|
|
|
|
|
|
|
// if(m_maskDataAddress)
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(0x3FFF);
|
|
|
|
m_codeGen->And();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-09 02:52:38 +00:00
|
|
|
void CMA_VU::CLower::CompileInstruction(uint32 nAddress, CCodeGen* codeGen, CMIPS* pCtx, bool nParent)
|
2006-06-15 04:19:30 +00:00
|
|
|
{
|
2008-06-15 19:55:28 +00:00
|
|
|
uint32 nPrevOpcode = pCtx->m_pMemoryMap->GetInstruction(nAddress - 8);
|
|
|
|
uint32 nNextOpcode = pCtx->m_pMemoryMap->GetInstruction(nAddress + 4);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
if(nNextOpcode & 0x80000000)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
m_nDest = (uint8 )((m_nOpcode >> 21) & 0x000F);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
m_nFSF = ((m_nDest >> 0) & 0x03);
|
|
|
|
m_nFTF = ((m_nDest >> 2) & 0x03);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
m_nIT = (uint8 )((m_nOpcode >> 16) & 0x001F);
|
|
|
|
m_nIS = (uint8 )((m_nOpcode >> 11) & 0x001F);
|
|
|
|
m_nID = (uint8 )((m_nOpcode >> 6) & 0x001F);
|
|
|
|
m_nImm5 = m_nID;
|
|
|
|
m_nImm11 = (uint16)((m_nOpcode >> 0) & 0x07FF);
|
2008-06-17 02:14:22 +00:00
|
|
|
m_nImm12 = (uint16)((m_nOpcode >> 0) & 0x0FFF);
|
2008-03-24 01:18:20 +00:00
|
|
|
m_nImm15 = (uint16)((m_nOpcode & 0x7FF) | (m_nOpcode & 0x01E00000) >> 10);
|
|
|
|
m_nImm15S = m_nImm15 | (m_nImm15 & 0x4000 ? 0x8000 : 0x0000);
|
|
|
|
m_nImm24 = m_nOpcode & 0x00FFFFFF;
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
if(m_nOpcode != 0x8000033C)
|
|
|
|
{
|
|
|
|
m_pOpGeneral[m_nOpcode >> 25]();
|
|
|
|
}
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMA_VU::CLower::SetBranchAddress(bool nCondition, int32 nOffset)
|
|
|
|
{
|
2008-06-23 01:35:05 +00:00
|
|
|
const uint32 maxIAddr = 0x3FFF;
|
2008-03-24 01:18:20 +00:00
|
|
|
m_codeGen->BeginIfElse(nCondition);
|
|
|
|
{
|
2008-06-23 01:35:05 +00:00
|
|
|
m_codeGen->PushCst((m_nAddress + nOffset + 4) & maxIAddr);
|
2008-03-24 01:18:20 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr));
|
|
|
|
}
|
|
|
|
m_codeGen->BeginIfElseAlt();
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(MIPS_INVALID_PC);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr));
|
|
|
|
}
|
|
|
|
m_codeGen->EndIf();
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2006-07-18 12:08:40 +00:00
|
|
|
void CMA_VU::CLower::PushIntegerRegister(unsigned int nRegister)
|
|
|
|
{
|
2008-03-22 02:37:01 +00:00
|
|
|
if(nRegister == 0)
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[nRegister]));
|
|
|
|
}
|
2006-07-18 12:08:40 +00:00
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
uint32 CMA_VU::CLower::GetDestOffset(uint8 nDest)
|
|
|
|
{
|
|
|
|
if(nDest & 0x0001) return 0xC;
|
|
|
|
if(nDest & 0x0002) return 0x8;
|
|
|
|
if(nDest & 0x0004) return 0x4;
|
|
|
|
if(nDest & 0x0008) return 0x0;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//General Instructions
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//00
|
|
|
|
void CMA_VU::CLower::LQ()
|
|
|
|
{
|
2008-06-23 01:35:05 +00:00
|
|
|
ComputeMemAccessAddr(
|
|
|
|
m_nIS,
|
|
|
|
static_cast<uint32>(VUShared::GetImm11Offset(m_nImm11)),
|
|
|
|
0);
|
2008-11-10 01:46:02 +00:00
|
|
|
m_codeGen->PushRef(m_pCtx);
|
|
|
|
m_codeGen->PushCst(m_nIT);
|
|
|
|
m_codeGen->PushCst(m_nDest);
|
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&GetQuadWord), 4, false);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//01
|
|
|
|
void CMA_VU::CLower::SQ()
|
|
|
|
{
|
2008-06-23 01:35:05 +00:00
|
|
|
ComputeMemAccessAddr(
|
|
|
|
m_nIT,
|
|
|
|
static_cast<uint32>(VUShared::GetImm11Offset(m_nImm11)),
|
|
|
|
0);
|
2008-11-10 01:46:02 +00:00
|
|
|
m_codeGen->PushRef(m_pCtx);
|
|
|
|
m_codeGen->PushCst(m_nIS);
|
|
|
|
m_codeGen->PushCst(m_nDest);
|
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&SetQuadWord), 4, false);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//04
|
|
|
|
void CMA_VU::CLower::ILW()
|
|
|
|
{
|
2008-03-22 02:37:01 +00:00
|
|
|
//Push context
|
|
|
|
m_codeGen->PushRef(m_pCtx);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-03-22 02:37:01 +00:00
|
|
|
//Compute address
|
2008-06-23 01:35:05 +00:00
|
|
|
ComputeMemAccessAddr(
|
|
|
|
m_nIS,
|
|
|
|
static_cast<uint32>(VUShared::GetImm11Offset(m_nImm11)),
|
|
|
|
GetDestOffset(m_nDest));
|
2008-03-22 02:37:01 +00:00
|
|
|
|
|
|
|
//Read memory
|
2008-04-09 02:52:38 +00:00
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&CMemoryUtils::GetWordProxy), 2, true);
|
2008-03-22 02:37:01 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//05
|
|
|
|
void CMA_VU::CLower::ISW()
|
|
|
|
{
|
2008-04-06 20:38:34 +00:00
|
|
|
//Push context
|
|
|
|
m_codeGen->PushRef(m_pCtx);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-06 20:38:34 +00:00
|
|
|
//Compute value
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
m_codeGen->PushCst(0xFFFF);
|
|
|
|
m_codeGen->And();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-06 20:38:34 +00:00
|
|
|
//Compute address
|
2008-06-23 01:35:05 +00:00
|
|
|
ComputeMemAccessAddr(
|
|
|
|
m_nIS,
|
|
|
|
static_cast<uint32>(VUShared::GetImm11Offset(m_nImm11)),
|
|
|
|
GetDestOffset(m_nDest));
|
2008-04-06 20:38:34 +00:00
|
|
|
|
2008-04-09 02:52:38 +00:00
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&CMemoryUtils::SetWordProxy), 3, false);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//08
|
|
|
|
void CMA_VU::CLower::IADDIU()
|
|
|
|
{
|
2008-03-22 02:37:01 +00:00
|
|
|
PushIntegerRegister(m_nIS);
|
2008-03-24 01:18:20 +00:00
|
|
|
m_codeGen->PushCst(static_cast<uint16>(m_nImm15));
|
2008-03-22 02:37:01 +00:00
|
|
|
m_codeGen->Add();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//09
|
|
|
|
void CMA_VU::CLower::ISUBIU()
|
|
|
|
{
|
2008-03-24 01:18:20 +00:00
|
|
|
PushIntegerRegister(m_nIS);
|
|
|
|
m_codeGen->PushCst(static_cast<uint16>(m_nImm15));
|
|
|
|
m_codeGen->Sub();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//11
|
|
|
|
void CMA_VU::CLower::FCSET()
|
|
|
|
{
|
2008-04-18 01:09:44 +00:00
|
|
|
m_codeGen->PushCst(m_nImm24);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2CF));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//12
|
|
|
|
void CMA_VU::CLower::FCAND()
|
|
|
|
{
|
2008-04-20 20:55:03 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2CF));
|
|
|
|
m_codeGen->PushCst(m_nImm24);
|
|
|
|
m_codeGen->And();
|
2008-04-07 00:51:28 +00:00
|
|
|
|
2008-04-20 20:55:03 +00:00
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
m_codeGen->Cmp(CCodeGen::CONDITION_EQ);
|
2008-04-07 00:51:28 +00:00
|
|
|
|
2008-04-20 20:55:03 +00:00
|
|
|
m_codeGen->BeginIfElse(false);
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(1);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[1]));
|
|
|
|
}
|
|
|
|
m_codeGen->BeginIfElseAlt();
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[1]));
|
|
|
|
}
|
|
|
|
m_codeGen->EndIf();
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
//13
|
|
|
|
void CMA_VU::CLower::FCOR()
|
|
|
|
{
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2CF));
|
|
|
|
m_codeGen->PushCst(m_nImm24);
|
|
|
|
m_codeGen->Or();
|
|
|
|
m_codeGen->PushCst(0xFFFFFF);
|
|
|
|
m_codeGen->And();
|
|
|
|
|
|
|
|
m_codeGen->PushCst(0xFFFFFF);
|
|
|
|
m_codeGen->Cmp(CCodeGen::CONDITION_EQ);
|
|
|
|
|
|
|
|
m_codeGen->BeginIfElse(true);
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(1);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[1]));
|
|
|
|
}
|
|
|
|
m_codeGen->BeginIfElseAlt();
|
|
|
|
{
|
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[1]));
|
|
|
|
}
|
|
|
|
m_codeGen->EndIf();
|
|
|
|
}
|
|
|
|
|
2008-06-17 02:14:22 +00:00
|
|
|
//16
|
|
|
|
void CMA_VU::CLower::FSAND()
|
|
|
|
{
|
|
|
|
printf("Warning: Using FSAND.\r\n");
|
2008-06-23 01:35:05 +00:00
|
|
|
|
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2008-06-17 02:14:22 +00:00
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
//1A
|
|
|
|
void CMA_VU::CLower::FMAND()
|
|
|
|
{
|
2008-04-06 20:38:34 +00:00
|
|
|
printf("Warning: Using FMAND.\r\n");
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-06 20:38:34 +00:00
|
|
|
//MAC flag temp
|
|
|
|
m_codeGen->PushCst(0);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-06 20:38:34 +00:00
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2SF.nV[3 - i]));
|
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
m_codeGen->Cmp(CCodeGen::CONDITION_NE);
|
|
|
|
m_codeGen->Shl(4 + i);
|
|
|
|
m_codeGen->Or();
|
|
|
|
}
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-06 20:38:34 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
//1C
|
|
|
|
void CMA_VU::CLower::FCGET()
|
|
|
|
{
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2CF));
|
|
|
|
m_codeGen->PushCst(0xFFF);
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
//20
|
|
|
|
void CMA_VU::CLower::B()
|
|
|
|
{
|
2008-04-18 01:09:44 +00:00
|
|
|
m_codeGen->PushCst(1);
|
|
|
|
SetBranchAddress(true, VUShared::GetBranch(m_nImm11) + 4);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
//21
|
|
|
|
void CMA_VU::CLower::BAL()
|
|
|
|
{
|
|
|
|
//Save PC
|
|
|
|
m_codeGen->PushCst((m_nAddress + 0x10) / 0x8);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
|
|
|
|
m_codeGen->PushCst(1);
|
|
|
|
SetBranchAddress(true, VUShared::GetBranch(m_nImm11) + 4);
|
|
|
|
}
|
|
|
|
|
2008-06-15 19:55:28 +00:00
|
|
|
//24
|
|
|
|
void CMA_VU::CLower::JR()
|
|
|
|
{
|
|
|
|
//Compute new PC
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->PushCst(0xFFFF);
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->Shl(3);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr));
|
|
|
|
}
|
|
|
|
|
2006-07-04 22:07:57 +00:00
|
|
|
//25
|
|
|
|
void CMA_VU::CLower::JALR()
|
|
|
|
{
|
2008-05-28 02:29:57 +00:00
|
|
|
//Save PC
|
2008-06-15 19:55:28 +00:00
|
|
|
m_codeGen->PushCst((m_nAddress + 0x10) / 0x8);
|
2008-05-28 02:29:57 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
|
|
|
|
//Compute new PC
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
2008-06-07 17:57:36 +00:00
|
|
|
m_codeGen->PushCst(0xFFFF);
|
|
|
|
m_codeGen->And();
|
2008-05-28 02:29:57 +00:00
|
|
|
m_codeGen->Shl(3);
|
2008-06-15 19:55:28 +00:00
|
|
|
// m_codeGen->PushCst(0x4000);
|
|
|
|
// m_codeGen->Add();
|
2008-05-28 02:29:57 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr));
|
2006-07-04 22:07:57 +00:00
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
//28
|
|
|
|
void CMA_VU::CLower::IBEQ()
|
|
|
|
{
|
2008-04-06 20:38:34 +00:00
|
|
|
//Operand 1
|
|
|
|
PushIntegerRegister(m_nIS);
|
|
|
|
m_codeGen->PushCst(0xFFFF);
|
|
|
|
m_codeGen->And();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-06 20:38:34 +00:00
|
|
|
//Operand 2
|
|
|
|
PushIntegerRegister(m_nIT);
|
|
|
|
m_codeGen->PushCst(0xFFFF);
|
|
|
|
m_codeGen->And();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-06 20:38:34 +00:00
|
|
|
m_codeGen->Cmp(CCodeGen::CONDITION_EQ);
|
2006-07-18 12:08:40 +00:00
|
|
|
|
2008-04-09 02:52:38 +00:00
|
|
|
SetBranchAddress(true, VUShared::GetBranch(m_nImm11) + 4);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//29
|
|
|
|
void CMA_VU::CLower::IBNE()
|
|
|
|
{
|
2008-03-24 01:18:20 +00:00
|
|
|
//Operand 1
|
|
|
|
PushIntegerRegister(m_nIS);
|
|
|
|
m_codeGen->PushCst(0xFFFF);
|
|
|
|
m_codeGen->And();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
//Operand 2
|
|
|
|
PushIntegerRegister(m_nIT);
|
|
|
|
m_codeGen->PushCst(0xFFFF);
|
|
|
|
m_codeGen->And();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
m_codeGen->Cmp(CCodeGen::CONDITION_EQ);
|
2006-07-18 12:08:40 +00:00
|
|
|
|
2008-04-09 02:52:38 +00:00
|
|
|
SetBranchAddress(false, VUShared::GetBranch(m_nImm11) + 4);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//2C
|
|
|
|
void CMA_VU::CLower::IBLTZ()
|
|
|
|
{
|
2008-05-28 02:29:57 +00:00
|
|
|
//TODO: Merge IBLTZ and IBGEZ
|
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->PushCst(0x8000);
|
|
|
|
m_codeGen->And();
|
|
|
|
|
|
|
|
m_codeGen->Cmp(CCodeGen::CONDITION_EQ);
|
2008-04-07 00:51:28 +00:00
|
|
|
|
2008-05-28 02:29:57 +00:00
|
|
|
SetBranchAddress(false, VUShared::GetBranch(m_nImm11) + 4);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2006-07-04 22:07:57 +00:00
|
|
|
//2D
|
|
|
|
void CMA_VU::CLower::IBGTZ()
|
|
|
|
{
|
2008-05-28 02:29:57 +00:00
|
|
|
//TODO: Merge IBGTZ and IBLEZ
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->SeX16();
|
|
|
|
|
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
m_codeGen->Cmp(CCodeGen::CONDITION_GT);
|
2006-07-04 22:07:57 +00:00
|
|
|
|
2008-05-28 02:29:57 +00:00
|
|
|
SetBranchAddress(true, VUShared::GetBranch(m_nImm11) + 4);
|
2006-07-04 22:07:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//2E
|
|
|
|
void CMA_VU::CLower::IBLEZ()
|
|
|
|
{
|
2008-05-28 02:29:57 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->SeX16();
|
|
|
|
|
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
m_codeGen->Cmp(CCodeGen::CONDITION_GT);
|
2006-07-04 22:07:57 +00:00
|
|
|
|
2008-05-28 02:29:57 +00:00
|
|
|
SetBranchAddress(false, VUShared::GetBranch(m_nImm11) + 4);
|
2006-07-04 22:07:57 +00:00
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
//2F
|
|
|
|
void CMA_VU::CLower::IBGEZ()
|
|
|
|
{
|
2008-04-06 20:38:34 +00:00
|
|
|
m_codeGen->PushCst(0);
|
|
|
|
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->PushCst(0x8000);
|
|
|
|
m_codeGen->And();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-06 20:38:34 +00:00
|
|
|
m_codeGen->Cmp(CCodeGen::CONDITION_EQ);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-09 02:52:38 +00:00
|
|
|
SetBranchAddress(true, VUShared::GetBranch(m_nImm11) + 4);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//40
|
|
|
|
void CMA_VU::CLower::LOWEROP()
|
|
|
|
{
|
|
|
|
m_pOpLower[m_nOpcode & 0x3F]();
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//LowerOp Instructions
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//30
|
|
|
|
void CMA_VU::CLower::IADD()
|
|
|
|
{
|
2008-03-24 01:18:20 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
m_codeGen->Add();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nID]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//31
|
|
|
|
void CMA_VU::CLower::ISUB()
|
|
|
|
{
|
2008-04-20 20:55:03 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
m_codeGen->Sub();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nID]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//32
|
|
|
|
void CMA_VU::CLower::IADDI()
|
|
|
|
{
|
2008-04-18 01:09:44 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->PushCst(m_nImm5 | ((m_nImm5 & 0x10) != 0 ? 0xFFFFFFE0 : 0x0));
|
|
|
|
m_codeGen->Add();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//34
|
|
|
|
void CMA_VU::CLower::IAND()
|
|
|
|
{
|
2008-04-18 01:09:44 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
m_codeGen->And();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nID]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//35
|
|
|
|
void CMA_VU::CLower::IOR()
|
|
|
|
{
|
2008-04-06 20:38:34 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
m_codeGen->Or();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nID]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//3C
|
|
|
|
void CMA_VU::CLower::VECTOR0()
|
|
|
|
{
|
|
|
|
m_pOpVector0[(m_nOpcode >> 6) & 0x1F]();
|
|
|
|
}
|
|
|
|
|
|
|
|
//3D
|
|
|
|
void CMA_VU::CLower::VECTOR1()
|
|
|
|
{
|
|
|
|
m_pOpVector1[(m_nOpcode >> 6) & 0x1F]();
|
|
|
|
}
|
|
|
|
|
|
|
|
//3E
|
|
|
|
void CMA_VU::CLower::VECTOR2()
|
|
|
|
{
|
|
|
|
m_pOpVector2[(m_nOpcode >> 6) & 0x1F]();
|
|
|
|
}
|
|
|
|
|
|
|
|
//3F
|
|
|
|
void CMA_VU::CLower::VECTOR3()
|
|
|
|
{
|
|
|
|
m_pOpVector3[(m_nOpcode >> 6) & 0x1F]();
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//Vector0 Instructions
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//0C
|
|
|
|
void CMA_VU::CLower::MOVE()
|
|
|
|
{
|
2008-04-18 01:09:44 +00:00
|
|
|
VUShared::MOVE(m_codeGen, m_nDest, m_nIT, m_nIS);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//0D
|
|
|
|
void CMA_VU::CLower::LQI()
|
|
|
|
{
|
2008-06-23 01:35:05 +00:00
|
|
|
ComputeMemAccessAddr(m_nIS, 0, 0);
|
2008-11-10 01:46:02 +00:00
|
|
|
m_codeGen->PushRef(m_pCtx);
|
|
|
|
m_codeGen->PushCst(m_nIT);
|
|
|
|
m_codeGen->PushCst(m_nDest);
|
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&GetQuadWord), 4, false);
|
2008-06-23 01:35:05 +00:00
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
m_codeGen->PushCst(1);
|
|
|
|
m_codeGen->Add();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//0E
|
|
|
|
void CMA_VU::CLower::DIV()
|
|
|
|
{
|
2008-05-02 00:55:54 +00:00
|
|
|
VUShared::DIV(m_codeGen, m_nIS, m_nFSF, m_nIT, m_nFTF, m_nAddress, 2);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//0F
|
|
|
|
void CMA_VU::CLower::MTIR()
|
|
|
|
{
|
2008-04-06 20:38:34 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2[m_nIS].nV[m_nFSF]));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//19
|
|
|
|
void CMA_VU::CLower::MFP()
|
|
|
|
{
|
2008-04-20 20:55:03 +00:00
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if(!VUShared::DestinationHasElement(m_nDest, i)) continue;
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-20 20:55:03 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2P));
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2[m_nIT].nV[i]));
|
|
|
|
}
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1A
|
|
|
|
void CMA_VU::CLower::XTOP()
|
|
|
|
{
|
2008-03-22 02:37:01 +00:00
|
|
|
//Push context
|
|
|
|
m_codeGen->PushRef(m_pCtx);
|
|
|
|
|
|
|
|
//Compute Address
|
2008-06-15 19:55:28 +00:00
|
|
|
m_codeGen->PushCst(CVIF::VU_TOP);
|
2008-03-22 02:37:01 +00:00
|
|
|
|
2008-04-09 02:52:38 +00:00
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&CMemoryUtils::GetWordProxy), 2, true);
|
2008-03-22 02:37:01 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1B
|
|
|
|
void CMA_VU::CLower::XGKICK()
|
|
|
|
{
|
2008-03-24 01:18:20 +00:00
|
|
|
//Push context
|
|
|
|
m_codeGen->PushRef(m_pCtx);
|
|
|
|
|
|
|
|
//Push value
|
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIS]));
|
|
|
|
|
2008-03-25 00:07:10 +00:00
|
|
|
//Compute Address
|
2008-06-15 19:55:28 +00:00
|
|
|
m_codeGen->PushCst(CVIF::VU_XGKICK);
|
2008-03-25 00:07:10 +00:00
|
|
|
|
2008-04-09 02:52:38 +00:00
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&CMemoryUtils::SetWordProxy), 3, false);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
//1F
|
|
|
|
void CMA_VU::CLower::ESIN()
|
|
|
|
{
|
|
|
|
const unsigned int seriesLength = 5;
|
|
|
|
const uint32 seriesConstants[seriesLength] =
|
|
|
|
{
|
|
|
|
0x3F800000,
|
|
|
|
0xBE2AAAA4,
|
|
|
|
0x3C08873E,
|
|
|
|
0xB94FB21F,
|
|
|
|
0x362E9C14
|
|
|
|
};
|
|
|
|
const unsigned int seriesExponents[seriesLength] =
|
|
|
|
{
|
|
|
|
1,
|
|
|
|
3,
|
|
|
|
5,
|
|
|
|
7,
|
|
|
|
9
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
for(unsigned int i = 0; i < seriesLength; i++)
|
|
|
|
{
|
|
|
|
unsigned int exponent = seriesExponents[i];
|
|
|
|
float constant = *reinterpret_cast<const float*>(&seriesConstants[i]);
|
|
|
|
|
|
|
|
m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP2[m_nIS].nV[m_nFSF]));
|
|
|
|
for(unsigned int j = 0; j < exponent - 1; j++)
|
|
|
|
{
|
|
|
|
m_codeGen->PushTop();
|
|
|
|
m_codeGen->FP_Mul();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_codeGen->FP_PushCst(constant);
|
|
|
|
m_codeGen->FP_Mul();
|
|
|
|
|
|
|
|
if(i != 0)
|
|
|
|
{
|
|
|
|
m_codeGen->FP_Add();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_codeGen->FP_PullSingle(offsetof(CMIPS, m_State.nCOP2P));
|
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//Vector1 Instructions
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//0C
|
|
|
|
void CMA_VU::CLower::MR32()
|
|
|
|
{
|
2008-04-18 01:09:44 +00:00
|
|
|
VUShared::MR32(m_codeGen, m_nDest, m_nIT, m_nIS);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//0D
|
|
|
|
void CMA_VU::CLower::SQI()
|
|
|
|
{
|
2008-06-23 01:35:05 +00:00
|
|
|
ComputeMemAccessAddr(m_nIT, 0, 0);
|
2008-11-10 01:46:02 +00:00
|
|
|
m_codeGen->PushRef(m_pCtx);
|
|
|
|
m_codeGen->PushCst(m_nIS);
|
|
|
|
m_codeGen->PushCst(m_nDest);
|
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&SetQuadWord), 4, false);
|
2008-06-23 01:35:05 +00:00
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
m_codeGen->PushCst(1);
|
|
|
|
m_codeGen->Add();
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//0F
|
|
|
|
void CMA_VU::CLower::MFIR()
|
|
|
|
{
|
2008-04-18 01:09:44 +00:00
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if(!VUShared::DestinationHasElement(m_nDest, i)) continue;
|
2008-04-07 00:51:28 +00:00
|
|
|
|
2008-04-18 01:09:44 +00:00
|
|
|
PushIntegerRegister(m_nIS);
|
|
|
|
m_codeGen->SeX16();
|
|
|
|
m_codeGen->PullRel(VUShared::GetVectorElement(m_nIT, i));
|
|
|
|
}
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//10
|
|
|
|
void CMA_VU::CLower::RGET()
|
|
|
|
{
|
2008-06-07 17:57:36 +00:00
|
|
|
VUShared::RGET(m_codeGen, m_nDest, m_nIT);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2008-06-15 19:55:28 +00:00
|
|
|
//1A
|
|
|
|
void CMA_VU::CLower::XITOP()
|
|
|
|
{
|
|
|
|
//Push context
|
|
|
|
m_codeGen->PushRef(m_pCtx);
|
|
|
|
|
|
|
|
//Compute Address
|
|
|
|
m_codeGen->PushCst(CVIF::VU_ITOP);
|
|
|
|
|
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&CMemoryUtils::GetWordProxy), 2, true);
|
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//Vector2 Instructions
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
//0E
|
|
|
|
void CMA_VU::CLower::RSQRT()
|
|
|
|
{
|
|
|
|
VUShared::RSQRT(m_codeGen, m_nIS, m_nFSF, m_nIT, m_nFTF, m_nAddress, 2);
|
|
|
|
}
|
|
|
|
|
2006-07-04 22:07:57 +00:00
|
|
|
//0F
|
|
|
|
void CMA_VU::CLower::ILWR()
|
|
|
|
{
|
2008-05-28 02:29:57 +00:00
|
|
|
//Push context
|
|
|
|
m_codeGen->PushRef(m_pCtx);
|
2006-07-04 22:07:57 +00:00
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
//Compute address
|
|
|
|
ComputeMemAccessAddr(m_nIS, 0, GetDestOffset(m_nDest));
|
2006-07-04 22:07:57 +00:00
|
|
|
|
2008-05-28 02:29:57 +00:00
|
|
|
m_codeGen->Call(reinterpret_cast<void*>(&CMemoryUtils::GetWordProxy), 2, true);
|
2006-07-04 22:07:57 +00:00
|
|
|
|
2008-05-28 02:29:57 +00:00
|
|
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2VI[m_nIT]));
|
2006-07-04 22:07:57 +00:00
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
//10
|
|
|
|
void CMA_VU::CLower::RINIT()
|
|
|
|
{
|
2008-04-20 20:55:03 +00:00
|
|
|
VUShared::RINIT(m_codeGen, m_nIS, m_nFSF);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1E
|
|
|
|
void CMA_VU::CLower::ERCPR()
|
|
|
|
{
|
2008-04-20 20:55:03 +00:00
|
|
|
m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP2[m_nIS].nV[m_nFSF]));
|
|
|
|
m_codeGen->FP_Rcpl();
|
|
|
|
m_codeGen->FP_PullSingle(offsetof(CMIPS, m_State.nCOP2P));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//Vector3 Instructions
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//0E
|
|
|
|
void CMA_VU::CLower::WAITQ()
|
|
|
|
{
|
2008-05-02 00:55:54 +00:00
|
|
|
VUShared::WAITQ(m_codeGen);
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//1C
|
|
|
|
void CMA_VU::CLower::ERLENG()
|
|
|
|
{
|
2008-04-19 16:50:09 +00:00
|
|
|
///////////////////////////////////////////////////
|
|
|
|
//Raise all components to the power of 2
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-19 16:50:09 +00:00
|
|
|
m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP2[m_nIS].nV[0]));
|
|
|
|
m_codeGen->PushTop();
|
|
|
|
m_codeGen->FP_Mul();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-19 16:50:09 +00:00
|
|
|
m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP2[m_nIS].nV[1]));
|
|
|
|
m_codeGen->PushTop();
|
|
|
|
m_codeGen->FP_Mul();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-19 16:50:09 +00:00
|
|
|
m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP2[m_nIS].nV[2]));
|
|
|
|
m_codeGen->PushTop();
|
|
|
|
m_codeGen->FP_Mul();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-19 16:50:09 +00:00
|
|
|
///////////////////////////////////////////////////
|
|
|
|
//Sum all components
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-19 16:50:09 +00:00
|
|
|
m_codeGen->FP_Add();
|
|
|
|
m_codeGen->FP_Add();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-19 16:50:09 +00:00
|
|
|
///////////////////////////////////////////////////
|
|
|
|
//Extract root, inverse
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-19 16:50:09 +00:00
|
|
|
m_codeGen->FP_Rsqrt();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-04-19 16:50:09 +00:00
|
|
|
m_codeGen->FP_PullSingle(offsetof(CMIPS, m_State.nCOP2P));
|
2006-06-15 04:19:30 +00:00
|
|
|
}
|
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
//1E
|
|
|
|
void CMA_VU::CLower::WAITP()
|
|
|
|
{
|
|
|
|
//TODO: Flush pipe
|
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//Opcode Tables
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void (*CMA_VU::CLower::m_pOpGeneral[0x80])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
LQ, SQ, Illegal, Illegal, ILW, ISW, Illegal, Illegal,
|
|
|
|
//0x08
|
|
|
|
IADDIU, ISUBIU, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x10
|
2008-06-23 01:35:05 +00:00
|
|
|
Illegal, FCSET, FCAND, FCOR, Illegal, Illegal, FSAND, Illegal,
|
2006-06-15 04:19:30 +00:00
|
|
|
//0x18
|
2008-06-23 01:35:05 +00:00
|
|
|
Illegal, Illegal, FMAND, Illegal, FCGET, Illegal, Illegal, Illegal,
|
2006-06-15 04:19:30 +00:00
|
|
|
//0x20
|
2008-06-23 01:35:05 +00:00
|
|
|
B, BAL, Illegal, Illegal, JR, JALR, Illegal, Illegal,
|
2006-06-15 04:19:30 +00:00
|
|
|
//0x28
|
2006-07-04 22:07:57 +00:00
|
|
|
IBEQ, IBNE, Illegal, Illegal, IBLTZ, IBGTZ, IBLEZ, IBGEZ,
|
2006-06-15 04:19:30 +00:00
|
|
|
//0x30
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x38
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x40
|
|
|
|
LOWEROP, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x48
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x50
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x58
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x60
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x68
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x70
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x78
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
};
|
|
|
|
|
|
|
|
void (*CMA_VU::CLower::m_pOpLower[0x40])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x08
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x10
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x18
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x20
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x28
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x30
|
|
|
|
IADD, ISUB, IADDI, Illegal, IAND, IOR, Illegal, Illegal,
|
|
|
|
//0x38
|
|
|
|
Illegal, Illegal, Illegal, Illegal, VECTOR0, VECTOR1, VECTOR2, VECTOR3,
|
|
|
|
};
|
|
|
|
|
|
|
|
void (*CMA_VU::CLower::m_pOpVector0[0x20])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x08
|
|
|
|
Illegal, Illegal, Illegal, Illegal, MOVE, LQI, DIV, MTIR,
|
|
|
|
//0x10
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x18
|
2008-06-23 01:35:05 +00:00
|
|
|
Illegal, MFP, XTOP, XGKICK, Illegal, Illegal, Illegal, ESIN,
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void (*CMA_VU::CLower::m_pOpVector1[0x20])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x08
|
|
|
|
Illegal, Illegal, Illegal, Illegal, MR32, SQI, Illegal, MFIR,
|
|
|
|
//0x10
|
|
|
|
RGET, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x18
|
2008-06-15 19:55:28 +00:00
|
|
|
Illegal, Illegal, XITOP, Illegal, Illegal, Illegal, Illegal, Illegal,
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void (*CMA_VU::CLower::m_pOpVector2[0x20])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x08
|
2008-06-23 01:35:05 +00:00
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, RSQRT, ILWR,
|
2006-06-15 04:19:30 +00:00
|
|
|
//0x10
|
|
|
|
RINIT, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x18
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, ERCPR, Illegal,
|
|
|
|
};
|
|
|
|
|
|
|
|
void (*CMA_VU::CLower::m_pOpVector3[0x20])() =
|
|
|
|
{
|
|
|
|
//0x00
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x08
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, WAITQ, Illegal,
|
|
|
|
//0x10
|
|
|
|
Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal, Illegal,
|
|
|
|
//0x18
|
2008-06-23 01:35:05 +00:00
|
|
|
Illegal, Illegal, Illegal, Illegal, ERLENG, Illegal, WAITP, Illegal,
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|