2007-12-07 00:26:56 +00:00
|
|
|
#include "VUShared.h"
|
|
|
|
#include "MIPS.h"
|
|
|
|
#include "offsetof_def.h"
|
|
|
|
|
2008-05-02 00:55:54 +00:00
|
|
|
#define LATENCY_DIV (7)
|
|
|
|
#define LATENCY_SQRT (7)
|
|
|
|
#define LATENCY_RSQRT (13)
|
|
|
|
|
|
|
|
const VUShared::PIPEINFO g_pipeInfoQ =
|
|
|
|
{
|
|
|
|
offsetof(CMIPS, m_State.nCOP2Q),
|
|
|
|
// offsetof(CMIPS, m_State.pipeQ.heldValue),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2Q),
|
|
|
|
offsetof(CMIPS, m_State.pipeQ.target)
|
|
|
|
};
|
|
|
|
|
2007-12-07 00:26:56 +00:00
|
|
|
using namespace VUShared;
|
2008-02-28 02:16:54 +00:00
|
|
|
using namespace std;
|
2007-12-07 00:26:56 +00:00
|
|
|
|
|
|
|
bool VUShared::DestinationHasElement(uint8 nDest, unsigned int nElement)
|
|
|
|
{
|
|
|
|
return (nDest & (1 << (nElement ^ 0x03))) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32* VUShared::GetVectorElement(CMIPS* pCtx, unsigned int nReg, unsigned int nElement)
|
|
|
|
{
|
|
|
|
switch(nElement)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
return &pCtx->m_State.nCOP2[nReg].nV0;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
return &pCtx->m_State.nCOP2[nReg].nV1;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
return &pCtx->m_State.nCOP2[nReg].nV2;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
return &pCtx->m_State.nCOP2[nReg].nV3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t VUShared::GetVectorElement(unsigned int nRegister, unsigned int nElement)
|
|
|
|
{
|
|
|
|
return offsetof(CMIPS, m_State.nCOP2[nRegister].nV[nElement]);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32* VUShared::GetAccumulatorElement(CMIPS* pCtx, unsigned int nElement)
|
|
|
|
{
|
|
|
|
switch(nElement)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
return &pCtx->m_State.nCOP2A.nV0;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
return &pCtx->m_State.nCOP2A.nV1;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
return &pCtx->m_State.nCOP2A.nV2;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
return &pCtx->m_State.nCOP2A.nV3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-02-28 02:16:54 +00:00
|
|
|
size_t VUShared::GetAccumulatorElement(unsigned int nElement)
|
|
|
|
{
|
|
|
|
return offsetof(CMIPS, m_State.nCOP2A.nV[nElement]);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::PullVector(CMipsJitter* codeGen, uint8 dest, size_t vector)
|
2008-02-27 02:23:28 +00:00
|
|
|
{
|
2010-11-01 01:05:26 +00:00
|
|
|
codeGen->MD_PullRel(vector,
|
|
|
|
DestinationHasElement(dest, 0),
|
|
|
|
DestinationHasElement(dest, 1),
|
|
|
|
DestinationHasElement(dest, 2),
|
|
|
|
DestinationHasElement(dest, 3));
|
2008-02-27 02:23:28 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ADDA_base(CMipsJitter* codeGen, uint8 dest, size_t fs, size_t ft, bool expand)
|
2008-06-07 17:57:36 +00:00
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(fs);
|
|
|
|
if(expand)
|
|
|
|
{
|
|
|
|
codeGen->MD_PushRelExpand(ft);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(ft);
|
|
|
|
}
|
|
|
|
codeGen->MD_AddS();
|
|
|
|
PullVector(codeGen, dest, offsetof(CMIPS, m_State.nCOP2A));
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MADD_base(CMipsJitter* codeGen, uint8 dest, size_t fd, size_t fs, size_t ft, bool expand)
|
2008-06-17 02:14:22 +00:00
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2A));
|
|
|
|
codeGen->MD_PushRel(fs);
|
|
|
|
if(expand)
|
|
|
|
{
|
|
|
|
codeGen->MD_PushRelExpand(ft);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(ft);
|
|
|
|
}
|
|
|
|
codeGen->MD_MulS();
|
|
|
|
codeGen->MD_AddS();
|
|
|
|
PullVector(codeGen, dest, fd);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MSUB_base(CMipsJitter* codeGen, uint8 dest, size_t fd, size_t fs, size_t ft, bool expand)
|
2008-06-07 17:57:36 +00:00
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2A));
|
|
|
|
codeGen->MD_PushRel(fs);
|
|
|
|
if(expand)
|
|
|
|
{
|
|
|
|
codeGen->MD_PushRelExpand(ft);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(ft);
|
|
|
|
}
|
|
|
|
codeGen->MD_MulS();
|
|
|
|
codeGen->MD_SubS();
|
|
|
|
PullVector(codeGen, dest, fd);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ABS(CMipsJitter* codeGen, uint8 nDest, uint8 nFt, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-04 01:50:41 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_AbsS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFt]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ADD(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-02-27 02:23:28 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFt]));
|
|
|
|
codeGen->MD_AddS();
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
//Get result flags
|
|
|
|
codeGen->PushTop();
|
|
|
|
codeGen->PushTop();
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
codeGen->MD_IsNegative();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2SF));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
codeGen->MD_IsZero();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2ZF));
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
//Save result
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ADDbc(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt, uint8 nBc)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-02-29 02:11:27 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2[nFt].nV[nBc]));
|
|
|
|
codeGen->MD_AddS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ADDi(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-18 01:09:44 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2I));
|
|
|
|
codeGen->MD_AddS();
|
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ADDq(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint32 address)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-05-02 00:55:54 +00:00
|
|
|
VerifyPipeline(g_pipeInfoQ, codeGen, address);
|
2008-02-29 02:11:27 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2Q));
|
|
|
|
codeGen->MD_AddS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ADDA(CMipsJitter* codeGen, uint8 dest, uint8 fs, uint8 ft)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-06-07 17:57:36 +00:00
|
|
|
ADDA_base(codeGen, dest,
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fs]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[ft]),
|
|
|
|
false);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ADDAbc(CMipsJitter* codeGen, uint8 dest, uint8 fs, uint8 ft, uint8 bc)
|
2008-06-07 17:57:36 +00:00
|
|
|
{
|
|
|
|
ADDA_base(codeGen, dest,
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fs]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[ft].nV[bc]),
|
|
|
|
true);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::CLIP(CMipsJitter* codeGen, uint8 nFs, uint8 nFt)
|
|
|
|
{
|
|
|
|
//Reimplement
|
|
|
|
assert(0);
|
|
|
|
|
|
|
|
// //Create some space for the new test results
|
|
|
|
// codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2CF));
|
|
|
|
// codeGen->Shl(6);
|
|
|
|
// codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2CF));
|
|
|
|
|
|
|
|
// for(unsigned int i = 0; i < 3; i++)
|
|
|
|
// {
|
|
|
|
// //c > +|w|
|
|
|
|
// codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP2[nFt].nV[3]));
|
|
|
|
// codeGen->FP_Abs();
|
|
|
|
// codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP2[nFs].nV[i]));
|
|
|
|
//codeGen->FP_Cmp(Jitter::CONDITION_AB);
|
|
|
|
|
|
|
|
// codeGen->BeginIf(true);
|
|
|
|
// {
|
|
|
|
// codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2CF));
|
|
|
|
// codeGen->PushCst(1 << ((i * 2) + 0));
|
|
|
|
// codeGen->Or();
|
|
|
|
// codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2CF));
|
|
|
|
// }
|
|
|
|
// codeGen->EndIf();
|
|
|
|
|
|
|
|
// //c < -|w|
|
|
|
|
// codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP2[nFt].nV[3]));
|
|
|
|
// codeGen->FP_Abs();
|
|
|
|
// codeGen->FP_Neg();
|
|
|
|
// codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP2[nFs].nV[i]));
|
|
|
|
// codeGen->FP_Cmp(Jitter::CONDITION_BL);
|
|
|
|
|
|
|
|
// codeGen->BeginIf(true);
|
|
|
|
// {
|
|
|
|
// codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2CF));
|
|
|
|
// codeGen->PushCst(1 << ((i * 2) + 1));
|
|
|
|
// codeGen->Or();
|
|
|
|
// codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2CF));
|
|
|
|
// }
|
|
|
|
// codeGen->EndIf();
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
void VUShared::DIV(CMipsJitter* codeGen, uint8 nFs, uint8 nFsf, uint8 nFt, uint8 nFtf, uint32 address, unsigned int pipeMult)
|
|
|
|
{
|
2010-11-01 01:05:26 +00:00
|
|
|
size_t destination = g_pipeInfoQ.heldValue;
|
|
|
|
QueueInPipeline(g_pipeInfoQ, codeGen, address + (pipeMult * 4 * LATENCY_DIV));
|
2010-09-03 21:13:57 +00:00
|
|
|
|
2010-11-01 01:05:26 +00:00
|
|
|
//Check for zero
|
|
|
|
codeGen->PushRel(GetVectorElement(nFt, nFtf));
|
|
|
|
codeGen->PushCst(0x7FFFFFFF);
|
|
|
|
codeGen->And();
|
|
|
|
codeGen->PushCst(0);
|
|
|
|
codeGen->BeginIf(Jitter::CONDITION_EQ);
|
|
|
|
{
|
|
|
|
codeGen->PushCst(0x7F7FFFFF);
|
|
|
|
codeGen->PushRel(GetVectorElement(nFs, nFsf));
|
|
|
|
codeGen->PushRel(GetVectorElement(nFt, nFtf));
|
|
|
|
codeGen->Xor();
|
|
|
|
codeGen->PushCst(0x80000000);
|
|
|
|
codeGen->And();
|
|
|
|
codeGen->Or();
|
|
|
|
codeGen->PullRel(destination);
|
|
|
|
}
|
|
|
|
codeGen->Else();
|
|
|
|
{
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFs, nFsf));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, nFtf));
|
|
|
|
codeGen->FP_Div();
|
|
|
|
codeGen->FP_PullSingle(destination);
|
|
|
|
}
|
|
|
|
codeGen->EndIf();
|
2010-09-03 21:13:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void VUShared::FTOI0(CMipsJitter* codeGen, uint8 nDest, uint8 nFt, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-06 03:14:33 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_ToWordTruncate();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFt]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::FTOI4(CMipsJitter* codeGen, uint8 nDest, uint8 nFt, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-06 03:14:33 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushCstExpand(16.0f);
|
|
|
|
codeGen->MD_MulS();
|
|
|
|
codeGen->MD_ToWordTruncate();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFt]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::FTOI12(CMipsJitter* codeGen, uint8 nDest, uint8 nFt, uint8 nFs)
|
2008-06-17 02:14:22 +00:00
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushCstExpand(4096.0f);
|
|
|
|
codeGen->MD_MulS();
|
|
|
|
codeGen->MD_ToWordTruncate();
|
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFt]));
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ITOF0(CMipsJitter* codeGen, uint8 nDest, uint8 nFt, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-16 22:31:37 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_ToSingle();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFt]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ITOF4(CMipsJitter* codeGen, uint8 dest, uint8 ft, uint8 fs)
|
2008-06-15 19:55:28 +00:00
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[fs]));
|
|
|
|
codeGen->MD_ToSingle();
|
|
|
|
codeGen->MD_PushCstExpand(16.0f);
|
|
|
|
codeGen->MD_DivS();
|
|
|
|
PullVector(codeGen, dest, offsetof(CMIPS, m_State.nCOP2[ft]));
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ITOF12(CMipsJitter* codeGen, uint8 dest, uint8 ft, uint8 fs)
|
2008-06-15 19:55:28 +00:00
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[fs]));
|
|
|
|
codeGen->MD_ToSingle();
|
|
|
|
codeGen->MD_PushCstExpand(4096.0f);
|
|
|
|
codeGen->MD_DivS();
|
|
|
|
PullVector(codeGen, dest, offsetof(CMIPS, m_State.nCOP2[ft]));
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::ITOF15(CMipsJitter* codeGen, uint8 dest, uint8 ft, uint8 fs)
|
2008-06-09 00:06:58 +00:00
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[fs]));
|
|
|
|
codeGen->MD_ToSingle();
|
|
|
|
codeGen->MD_PushCstExpand(32768.0f);
|
|
|
|
codeGen->MD_DivS();
|
|
|
|
PullVector(codeGen, dest, offsetof(CMIPS, m_State.nCOP2[ft]));
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MADD(CMipsJitter* codeGen, uint8 dest, uint8 fd, uint8 fs, uint8 ft)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-06-17 02:14:22 +00:00
|
|
|
MADD_base(codeGen, dest,
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fd]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fs]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[ft]),
|
|
|
|
false);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MADDbc(CMipsJitter* codeGen, uint8 dest, uint8 fd, uint8 fs, uint8 ft, uint8 bc)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-06-17 02:14:22 +00:00
|
|
|
MADD_base(codeGen, dest,
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fd]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fs]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[ft].nV[bc]),
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MADDq(CMipsJitter* codeGen, uint8 dest, uint8 fd, uint8 fs, uint32 address)
|
2008-06-17 02:14:22 +00:00
|
|
|
{
|
|
|
|
MADD_base(codeGen, dest,
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fd]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fs]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2Q),
|
|
|
|
true);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MADDA(CMipsJitter* codeGen, uint8 nDest, uint8 nFs, uint8 nFt)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-04 01:50:41 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2A));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFt]));
|
|
|
|
codeGen->MD_MulS();
|
|
|
|
codeGen->MD_AddS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2A));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MADDAbc(CMipsJitter* codeGen, uint8 nDest, uint8 nFs, uint8 nFt, uint8 nBc)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-02-28 02:16:54 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2A));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2[nFt].nV[nBc]));
|
|
|
|
codeGen->MD_MulS();
|
|
|
|
codeGen->MD_AddS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2A));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MADDAi(CMipsJitter* codeGen, uint8 nDest, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-04 01:50:41 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2A));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2I));
|
|
|
|
codeGen->MD_MulS();
|
|
|
|
codeGen->MD_AddS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2A));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MAX(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-16 22:31:37 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFt]));
|
|
|
|
codeGen->MD_MaxS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MAXbc(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt, uint8 nBc)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-15 16:20:36 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2[nFt].nV[nBc]));
|
|
|
|
codeGen->MD_MaxS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MINI(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-16 22:31:37 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFt]));
|
|
|
|
codeGen->MD_MinS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MINIbc(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt, uint8 nBc)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-15 16:20:36 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2[nFt].nV[nBc]));
|
|
|
|
codeGen->MD_MinS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MINIi(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-20 20:55:03 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2I));
|
|
|
|
codeGen->MD_MinS();
|
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MOVE(CMipsJitter* codeGen, uint8 nDest, uint8 nFt, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-02-29 02:11:27 +00:00
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if(!DestinationHasElement(nDest, i)) continue;
|
2007-12-07 00:26:56 +00:00
|
|
|
|
2008-02-29 02:11:27 +00:00
|
|
|
codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2[nFs].nV[i]));
|
|
|
|
codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2[nFt].nV[i]));
|
|
|
|
}
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MR32(CMipsJitter* codeGen, uint8 nDest, uint8 nFt, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2009-07-28 01:58:15 +00:00
|
|
|
size_t offset[4];
|
|
|
|
|
|
|
|
if(nFs == nFt)
|
|
|
|
{
|
|
|
|
offset[0] = offsetof(CMIPS, m_State.nCOP2[nFs].nV[1]);
|
|
|
|
offset[1] = offsetof(CMIPS, m_State.nCOP2[nFs].nV[2]);
|
|
|
|
offset[2] = offsetof(CMIPS, m_State.nCOP2[nFs].nV[3]);
|
|
|
|
offset[3] = offsetof(CMIPS, m_State.nCOP2T);
|
|
|
|
|
|
|
|
codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2[nFs].nV[0]));
|
|
|
|
codeGen->PullRel(offset[3]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
offset[0] = offsetof(CMIPS, m_State.nCOP2[nFs].nV[1]);
|
|
|
|
offset[1] = offsetof(CMIPS, m_State.nCOP2[nFs].nV[2]);
|
|
|
|
offset[2] = offsetof(CMIPS, m_State.nCOP2[nFs].nV[3]);
|
|
|
|
offset[3] = offsetof(CMIPS, m_State.nCOP2[nFs].nV[0]);
|
|
|
|
}
|
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if(!DestinationHasElement(nDest, i)) continue;
|
2009-07-28 01:58:15 +00:00
|
|
|
codeGen->PushRel(offset[i]);
|
2008-02-27 02:23:28 +00:00
|
|
|
codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2[nFt].nV[i]));
|
|
|
|
}
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MSUBbc(CMipsJitter* codeGen, uint8 dest, uint8 fd, uint8 fs, uint8 ft, uint8 bc)
|
2008-06-07 17:57:36 +00:00
|
|
|
{
|
|
|
|
MSUB_base(codeGen, dest,
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fd]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[fs]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[ft].nV[bc]),
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MSUBi(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs)
|
2008-06-07 17:57:36 +00:00
|
|
|
{
|
|
|
|
MSUB_base(codeGen, nDest,
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[nFd]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2[nFs]),
|
|
|
|
offsetof(CMIPS, m_State.nCOP2I),
|
|
|
|
true);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MSUBAbc(CMipsJitter* codeGen, uint8 dest, uint8 fs, uint8 ft, uint8 bc)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-04 01:50:41 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2A));
|
2008-06-07 17:57:36 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[fs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2[ft].nV[bc]));
|
2008-04-04 01:50:41 +00:00
|
|
|
codeGen->MD_MulS();
|
|
|
|
codeGen->MD_SubS();
|
2008-06-07 17:57:36 +00:00
|
|
|
PullVector(codeGen, dest, offsetof(CMIPS, m_State.nCOP2A));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MSUBAi(CMipsJitter* codeGen, uint8 nDest, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-04 01:50:41 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2A));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2I));
|
|
|
|
codeGen->MD_MulS();
|
|
|
|
codeGen->MD_SubS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2A));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MUL(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-02-29 02:11:27 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFt]));
|
|
|
|
codeGen->MD_MulS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MULbc(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt, uint8 nBc)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-03 00:38:28 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2[nFt].nV[nBc]));
|
|
|
|
codeGen->MD_MulS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MULi(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-24 01:18:20 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2I));
|
|
|
|
codeGen->MD_MulS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MULq(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint32 address)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-05-02 00:55:54 +00:00
|
|
|
VerifyPipeline(g_pipeInfoQ, codeGen, address);
|
2008-02-29 02:11:27 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2Q));
|
|
|
|
codeGen->MD_MulS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MULA(CMipsJitter* codeGen, uint8 nDest, uint8 nFs, uint8 nFt)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-04 01:50:41 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFt]));
|
|
|
|
codeGen->MD_MulS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2A));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MULAbc(CMipsJitter* codeGen, uint8 nDest, uint8 nFs, uint8 nFt, uint8 nBc)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-02-28 02:16:54 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2[nFt].nV[nBc]));
|
|
|
|
codeGen->MD_MulS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2A));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::MULAi(CMipsJitter* codeGen, uint8 nDest, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-04 01:50:41 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2I));
|
|
|
|
codeGen->MD_MulS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2A));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::OPMULA(CMipsJitter* codeGen, uint8 nFs, uint8 nFt)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-02-28 02:16:54 +00:00
|
|
|
//ACCx
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFs, VECTOR_COMPY));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, VECTOR_COMPZ));
|
|
|
|
codeGen->FP_Mul();
|
|
|
|
codeGen->FP_PullSingle(GetAccumulatorElement(VECTOR_COMPX));
|
|
|
|
|
|
|
|
//ACCy
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFs, VECTOR_COMPZ));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, VECTOR_COMPX));
|
|
|
|
codeGen->FP_Mul();
|
|
|
|
codeGen->FP_PullSingle(GetAccumulatorElement(VECTOR_COMPY));
|
|
|
|
|
|
|
|
//ACCz
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFs, VECTOR_COMPX));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, VECTOR_COMPY));
|
|
|
|
codeGen->FP_Mul();
|
|
|
|
codeGen->FP_PullSingle(GetAccumulatorElement(VECTOR_COMPZ));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::OPMSUB(CMipsJitter* codeGen, uint8 nFd, uint8 nFs, uint8 nFt)
|
|
|
|
{
|
2010-11-01 01:05:26 +00:00
|
|
|
if(nFd == 0)
|
|
|
|
{
|
|
|
|
//Gotta test this further
|
|
|
|
assert(0);
|
|
|
|
|
|
|
|
//Atelier Iris - OPMSUB with VF0 as FD...
|
|
|
|
//This is probably to set a flag which is tested a bit further
|
|
|
|
//The flag tested is Sz
|
|
|
|
codeGen->PushCst(0);
|
|
|
|
|
|
|
|
codeGen->FP_PushSingle(GetAccumulatorElement(VECTOR_COMPZ));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFs, VECTOR_COMPX));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, VECTOR_COMPY));
|
|
|
|
codeGen->FP_Mul();
|
|
|
|
codeGen->FP_Sub();
|
|
|
|
|
|
|
|
codeGen->FP_Cmp(Jitter::CONDITION_BL);
|
|
|
|
|
|
|
|
codeGen->PushCst(0);
|
|
|
|
codeGen->BeginIf(Jitter::CONDITION_NE);
|
|
|
|
{
|
|
|
|
codeGen->PushCst(0xFFFFFFFF);
|
|
|
|
codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2SF.nV[2]));
|
|
|
|
}
|
|
|
|
codeGen->Else();
|
|
|
|
{
|
|
|
|
codeGen->PushCst(0);
|
|
|
|
codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2SF.nV[2]));
|
|
|
|
}
|
|
|
|
codeGen->EndIf();
|
|
|
|
return;
|
|
|
|
}
|
2010-09-03 21:13:57 +00:00
|
|
|
|
2010-11-01 01:05:26 +00:00
|
|
|
//X
|
|
|
|
codeGen->FP_PushSingle(GetAccumulatorElement(VECTOR_COMPX));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFs, VECTOR_COMPY));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, VECTOR_COMPZ));
|
|
|
|
codeGen->FP_Mul();
|
|
|
|
codeGen->FP_Sub();
|
|
|
|
codeGen->FP_PullSingle(GetVectorElement(nFd, VECTOR_COMPX));
|
|
|
|
|
|
|
|
//Y
|
|
|
|
codeGen->FP_PushSingle(GetAccumulatorElement(VECTOR_COMPY));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFs, VECTOR_COMPZ));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, VECTOR_COMPX));
|
|
|
|
codeGen->FP_Mul();
|
|
|
|
codeGen->FP_Sub();
|
|
|
|
codeGen->FP_PullSingle(GetVectorElement(nFd, VECTOR_COMPY));
|
|
|
|
|
|
|
|
//Z
|
|
|
|
codeGen->FP_PushSingle(GetAccumulatorElement(VECTOR_COMPZ));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFs, VECTOR_COMPX));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, VECTOR_COMPY));
|
|
|
|
codeGen->FP_Mul();
|
|
|
|
codeGen->FP_Sub();
|
|
|
|
codeGen->FP_PullSingle(GetVectorElement(nFd, VECTOR_COMPZ));
|
2010-09-03 21:13:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void VUShared::RINIT(CMipsJitter* codeGen, uint8 nFs, uint8 nFsf)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-20 20:55:03 +00:00
|
|
|
codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2[nFs].nV[nFsf]));
|
|
|
|
codeGen->PushCst(0x007FFFFF);
|
|
|
|
codeGen->And();
|
|
|
|
codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2R));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::RGET(CMipsJitter* codeGen, uint8 dest, uint8 ft)
|
2008-06-07 17:57:36 +00:00
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if(!VUShared::DestinationHasElement(dest, i)) continue;
|
|
|
|
|
|
|
|
codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2R));
|
|
|
|
codeGen->PushCst(0x3F800000);
|
|
|
|
codeGen->Or();
|
|
|
|
codeGen->PullRel(VUShared::GetVectorElement(ft, i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::RNEXT(CMipsJitter* codeGen, uint8 dest, uint8 ft)
|
2008-06-07 17:57:36 +00:00
|
|
|
{
|
|
|
|
//Compute next R
|
|
|
|
codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2R));
|
|
|
|
codeGen->PushCst(0xDEADBEEF);
|
|
|
|
codeGen->Xor();
|
|
|
|
codeGen->PushCst(0xDEADBEEF);
|
|
|
|
codeGen->Add();
|
|
|
|
codeGen->PushCst(0x007FFFFF);
|
|
|
|
codeGen->And();
|
|
|
|
codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2R));
|
|
|
|
|
|
|
|
RGET(codeGen, dest, ft);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::RSQRT(CMipsJitter* codeGen, uint8 nFs, uint8 nFsf, uint8 nFt, uint8 nFtf, uint32 address, unsigned int pipeMult)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-05-02 00:55:54 +00:00
|
|
|
size_t destination = g_pipeInfoQ.heldValue;
|
|
|
|
QueueInPipeline(g_pipeInfoQ, codeGen, address + (pipeMult * 4 * LATENCY_RSQRT));
|
|
|
|
|
2008-03-03 00:38:28 +00:00
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFs, nFsf));
|
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, nFtf));
|
|
|
|
codeGen->FP_Rsqrt();
|
|
|
|
codeGen->FP_Mul();
|
2008-05-02 00:55:54 +00:00
|
|
|
codeGen->FP_PullSingle(destination);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::RXOR(CMipsJitter* codeGen, uint8 nFs, uint8 nFsf)
|
2008-05-28 02:29:57 +00:00
|
|
|
{
|
|
|
|
codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2[nFs].nV[nFsf]));
|
|
|
|
codeGen->PushRel(offsetof(CMIPS, m_State.nCOP2R));
|
|
|
|
codeGen->Xor();
|
|
|
|
codeGen->PushCst(0x007FFFFF);
|
|
|
|
codeGen->And();
|
|
|
|
codeGen->PullRel(offsetof(CMIPS, m_State.nCOP2R));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::SQRT(CMipsJitter* codeGen, uint8 nFt, uint8 nFtf, uint32 address, unsigned int pipeMult)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-05-02 00:55:54 +00:00
|
|
|
size_t destination = g_pipeInfoQ.heldValue;
|
|
|
|
QueueInPipeline(g_pipeInfoQ, codeGen, address + (pipeMult * 4 * LATENCY_SQRT));
|
|
|
|
|
2008-02-29 02:11:27 +00:00
|
|
|
codeGen->FP_PushSingle(GetVectorElement(nFt, nFtf));
|
|
|
|
codeGen->FP_Sqrt();
|
2008-05-02 00:55:54 +00:00
|
|
|
codeGen->FP_PullSingle(destination);
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::SUB(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-02-27 02:23:28 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFt]));
|
|
|
|
codeGen->MD_SubS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::SUBbc(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs, uint8 nFt, uint8 nBc)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-03-15 16:20:36 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2[nFt].nV[nBc]));
|
|
|
|
codeGen->MD_SubS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::SUBi(CMipsJitter* codeGen, uint8 nDest, uint8 nFd, uint8 nFs)
|
2007-12-07 00:26:56 +00:00
|
|
|
{
|
2008-04-04 01:50:41 +00:00
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[nFs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2I));
|
|
|
|
codeGen->MD_SubS();
|
2008-04-09 02:52:38 +00:00
|
|
|
PullVector(codeGen, nDest, offsetof(CMIPS, m_State.nCOP2[nFd]));
|
2007-12-07 00:26:56 +00:00
|
|
|
}
|
2008-05-02 00:55:54 +00:00
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::SUBAbc(CMipsJitter* codeGen, uint8 dest, uint8 fs, uint8 ft, uint8 bc)
|
2008-06-07 17:57:36 +00:00
|
|
|
{
|
|
|
|
codeGen->MD_PushRel(offsetof(CMIPS, m_State.nCOP2[fs]));
|
|
|
|
codeGen->MD_PushRelExpand(offsetof(CMIPS, m_State.nCOP2[ft].nV[bc]));
|
|
|
|
codeGen->MD_SubS();
|
|
|
|
PullVector(codeGen, dest, offsetof(CMIPS, m_State.nCOP2A));
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::WAITQ(CMipsJitter* codeGen)
|
2008-05-02 00:55:54 +00:00
|
|
|
{
|
|
|
|
FlushPipeline(g_pipeInfoQ, codeGen);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::FlushPipeline(const PIPEINFO& pipeInfo, CMipsJitter* codeGen)
|
2008-05-02 00:55:54 +00:00
|
|
|
{
|
2010-11-01 01:05:26 +00:00
|
|
|
return;
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
//Reimplement
|
|
|
|
assert(0);
|
2008-05-02 00:55:54 +00:00
|
|
|
|
2010-11-01 01:05:26 +00:00
|
|
|
//Dump the current value if one pending
|
|
|
|
//codeGen->PushCst(MIPS_INVALID_PC);
|
|
|
|
//codeGen->PushRel(pipeInfo.target);
|
|
|
|
//codeGen->Cmp(Jitter::CONDITION_EQ);
|
2008-05-02 00:55:54 +00:00
|
|
|
|
2010-11-01 01:05:26 +00:00
|
|
|
//codeGen->BeginIf(false);
|
|
|
|
//{
|
|
|
|
// codeGen->PushRel(pipeInfo.heldValue);
|
|
|
|
// codeGen->PullRel(pipeInfo.value);
|
2010-09-03 21:13:57 +00:00
|
|
|
|
2010-11-01 01:05:26 +00:00
|
|
|
// codeGen->PushCst(MIPS_INVALID_PC);
|
|
|
|
// codeGen->PullRel(pipeInfo.target);
|
|
|
|
//}
|
|
|
|
//codeGen->EndIf();
|
2008-05-02 00:55:54 +00:00
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::QueueInPipeline(const PIPEINFO& pipeInfo, CMipsJitter* codeGen, uint32 targetAddress)
|
2008-05-02 00:55:54 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
|
|
|
|
FlushPipeline(pipeInfo, codeGen);
|
|
|
|
|
|
|
|
//Set target
|
|
|
|
codeGen->PushCst(targetAddress);
|
|
|
|
codeGen->PullRel(pipeInfo.target);
|
|
|
|
}
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
void VUShared::VerifyPipeline(const PIPEINFO& pipeInfo, CMipsJitter* codeGen, uint32 currentAddress)
|
2008-05-02 00:55:54 +00:00
|
|
|
{
|
2010-11-01 01:05:26 +00:00
|
|
|
return;
|
|
|
|
|
2010-09-03 21:13:57 +00:00
|
|
|
//Reimplement
|
|
|
|
assert(0);
|
2010-11-01 01:05:26 +00:00
|
|
|
|
|
|
|
//Dump current value if it's ready
|
|
|
|
//codeGen->PushCst(currentAddress);
|
|
|
|
//codeGen->PushRel(pipeInfo.target);
|
|
|
|
//codeGen->Cmp(Jitter::CONDITION_BL);
|
|
|
|
|
|
|
|
//codeGen->BeginIf(false);
|
|
|
|
//{
|
|
|
|
// codeGen->PushRel(pipeInfo.heldValue);
|
|
|
|
// codeGen->PullRel(pipeInfo.value);
|
|
|
|
|
|
|
|
// codeGen->PushCst(MIPS_INVALID_PC);
|
|
|
|
// codeGen->PullRel(pipeInfo.target);
|
|
|
|
//}
|
|
|
|
//codeGen->EndIf();
|
2008-05-02 00:55:54 +00:00
|
|
|
}
|