COP2: Simplify reg allocation

This commit is contained in:
refractionpcsx2 2021-10-13 21:46:48 +01:00
parent 45bb57a38c
commit a96f900760
5 changed files with 162 additions and 167 deletions

View File

@ -745,66 +745,69 @@ void _freeXMMreg(u32 xmmreg)
xmmregs[xmmreg].inuse = 0;
}
u16 _freeXMMregsCOP2(int requiredcount)
void _clearNeededCOP2Regs()
{
int count = requiredcount;
u16 regs = 0;
for (size_t i = 0; i < iREGCNT_XMM - 1; i++)
{
if (xmmregs[i].inuse && xmmregs[i].type == XMMTYPE_VFREG)
{
xmmregs[i].inuse = false;
xmmregs[i].type = XMMTYPE_VFREG;
xmmregs[i].counter = 0;
}
}
}
u16 _freeXMMregsCOP2()
{
// First check what's already free, it might be enough
for (size_t i = 0; i < iREGCNT_XMM - 1; i++)
{
if (!xmmregs[i].inuse)
{
count--;
regs |= (1 << i);
xmmregs[i].inuse = true;
xmmregs[i].type = XMMTYPE_VFREG;
xmmregs[i].counter = 9999;
return i;
}
}
if (count <= 0)
return regs;
// If we still don't have enough, find regs in use but not needed
for (size_t i = 0; i < iREGCNT_XMM - 1; i++)
{
if (xmmregs[i].inuse && xmmregs[i].counter == 0)
{
count--;
regs |= (1 << i);
_freeXMMreg(i);
xmmregs[i].inuse = true;
xmmregs[i].type = XMMTYPE_VFREG;
xmmregs[i].counter = 9999;
return i;
}
if (count <= 0)
break;
}
if (count <= 0)
return regs;
// Finally Get rid of registers which are gonna be needed, they'll need to be reloaded
int maxcount = 9999; // The lower this value the more towards the end of the block it'll need flushing
int regtoclear = -1;
int maxcount = 9999;
while (count > 0)
for (size_t i = 0; i < iREGCNT_XMM - 1; i++)
{
for (size_t i = 0; i < iREGCNT_XMM - 1; i++)
if (xmmregs[i].inuse && xmmregs[i].counter < maxcount)
{
if (xmmregs[i].inuse && xmmregs[i].counter < maxcount)
{
regtoclear = i;
maxcount = xmmregs[i].counter;
}
}
if (regtoclear != -1)
{
_freeXMMreg(regtoclear);
count--;
regs |= (1 << regtoclear);
regtoclear = i;
maxcount = xmmregs[i].counter;
}
}
if (regtoclear != -1)
{
_freeXMMreg(regtoclear);
xmmregs[regtoclear].inuse = true;
xmmregs[regtoclear].type = XMMTYPE_VFREG;
xmmregs[regtoclear].counter = 9999;
return regtoclear;
}
pxAssert(count <= 0);
pxAssert(0);
return regs;
return -1;
}
// Return the number of inuse XMM register that have the MODE_WRITE flag

View File

@ -176,7 +176,8 @@ void _clearNeededXMMregs();
void _deleteGPRtoXMMreg(int reg, int flush);
void _deleteFPtoXMMreg(int reg, int flush);
void _freeXMMreg(u32 xmmreg);
u16 _freeXMMregsCOP2(int requiredcount);
void _clearNeededCOP2Regs();
u16 _freeXMMregsCOP2();
//void _moveXMMreg(int xmmreg); // instead of freeing, moves it to a diff location
void _flushXMMregs();
u8 _hasFreeXMMreg();

View File

@ -674,7 +674,7 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
// First Pass
iPC = startPC / 4;
mVUsetupRange(mVU, startPC, 1); // Setup Program Bounds/Range
mVU.regAlloc->reset(); // Reset regAlloc
mVU.regAlloc->reset(false); // Reset regAlloc
mVUinitFirstPass(mVU, pState, thisPtr);
mVUbranch = 0;
for (int branch = 0; mVUcount < endCount;)

View File

@ -14,6 +14,7 @@
*/
#pragma once
#include "microVU.h"
union regInfo
{
@ -232,6 +233,7 @@ protected:
microMapXMM xmmMap[xmmTotal];
int counter; // Current allocation count
int index; // VU0 or VU1
bool regAllocCOP2; // Local COP2 check
// Helper functions to get VU regs
VURegs& regs() const { return ::vuRegs[index]; }
@ -262,6 +264,11 @@ protected:
int findFreeReg()
{
if (regAllocCOP2)
{
return _freeXMMregsCOP2();
}
for (int i = 0; i < xmmTotal; i++)
{
if (!xmmMap[i].isNeeded && (xmmMap[i].VFreg < 0))
@ -278,30 +285,18 @@ public:
microRegAlloc(int _index)
{
index = _index;
reset();
reset(false);
}
// Fully resets the regalloc by clearing all cached data
void reset()
void reset(bool cop2mode)
{
for (int i = 0; i < xmmTotal; i++)
{
clearReg(i);
}
counter = 0;
}
void reserveCOP2(u16 regs)
{
u16 regmask = ~regs;
for (int i = 0; i < xmmTotal; i++)
{
if (regmask & (1 << i))
{
xmmMap[i].isNeeded = true;
xmmMap[i].xyzw = 1; // Not really, but it tricks the allocator in to thinking it's needed
}
}
regAllocCOP2 = cop2mode;
}
int getXmmCount()

View File

@ -32,7 +32,7 @@ using namespace R5900::Dynarec;
void setupMacroOp(int mode, const char* opName)
{
// Set up reg allocation
microVU0.regAlloc->reset();
microVU0.regAlloc->reset(true);
if (mode & 0x110) // X86 regs are modified, or flags modified
{
@ -44,12 +44,6 @@ void setupMacroOp(int mode, const char* opName)
if (mode & 0x03) // Q will be read/written
_freeXMMreg(xmmPQ.Id);
if (mode & 0xF000) // Number of XMM regs needed for op
{
u16 regs = _freeXMMregsCOP2(mode >> 12);
microVU0.regAlloc->reserveCOP2(regs);
}
// Set up MicroVU ready for new op
printCOP2(opName);
microVU0.cop2 = 1;
@ -96,6 +90,7 @@ void endMacroOp(int mode)
}
microVU0.regAlloc->flushAll();
_clearNeededCOP2Regs();
if (mode & 0x10) // Update VU0 Status/Mac instances after flush to avoid corrupting anything
{
@ -111,6 +106,7 @@ void endMacroOp(int mode)
_freeXMMreg(t0reg);
}
microVU0.cop2 = 0;
microVU0.regAlloc->reset(false);
}
#define REC_COP2_mVU0(f, opName, mode) \
@ -159,110 +155,110 @@ void endMacroOp(int mode)
0x8 write CLIP
0x10 writes status/mac
0x100 requires x86 regs
0xF000 number of required XMMs (0-15)
*/
REC_COP2_mVU0(ABS, "ABS", 0x1000);
REC_COP2_mVU0(ITOF0, "ITOF0", 0x1000);
REC_COP2_mVU0(ITOF4, "ITOF4", 0x1000);
REC_COP2_mVU0(ITOF12, "ITOF12", 0x1000);
REC_COP2_mVU0(ITOF15, "ITOF15", 0x1000);
REC_COP2_mVU0(FTOI0, "FTOI0", 0x3000);
REC_COP2_mVU0(FTOI4, "FTOI4", 0x3000);
REC_COP2_mVU0(FTOI12, "FTOI12", 0x3000);
REC_COP2_mVU0(FTOI15, "FTOI15", 0x3000);
REC_COP2_mVU0(ADD, "ADD", ((_cXYZW_SS2 || clampE) ? 0x2110 : 0x3110) + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(ADDi, "ADDi", 0x2110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(ADDq, "ADDq", 0x2111 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(ADDx, "ADDx", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(ADDy, "ADDy", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(ADDz, "ADDz", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(ADDw, "ADDw", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(ADDA, "ADDA", ((!(_cXYZW_SS2 || clampE) && !_cXYZW_SS) ? 0x4110 : 0x3110));
REC_COP2_mVU0(ADDAi, "ADDAi", 0x3110);
REC_COP2_mVU0(ADDAq, "ADDAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0));
REC_COP2_mVU0(ADDAx, "ADDAx", 0x4110);
REC_COP2_mVU0(ADDAy, "ADDAy", 0x4110);
REC_COP2_mVU0(ADDAz, "ADDAz", 0x4110);
REC_COP2_mVU0(ADDAw, "ADDAw", 0x4110);
REC_COP2_mVU0(SUB, "SUB", (_Rt_ == _Rd_) ? (!(_cXYZW_SS) ? 0x3110 : 0x2110) : ((_cXYZW_SS2 || clampE) ? 0x2110 : 0x3110) + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(SUBi, "SUBi", 0x2110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(SUBq, "SUBq", 0x2111 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(SUBx, "SUBx", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(SUBy, "SUBy", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(SUBz, "SUBz", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(SUBw, "SUBw", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(SUBA, "SUBA", (_Rt_ == _Rd_) ? (!(_cXYZW_SS) ? 0x3110 : 0x2110) : ((!clampE && !_cXYZW_SS) ? 0x4110 : 0x3110));
REC_COP2_mVU0(SUBAi, "SUBAi", 0x3110);
REC_COP2_mVU0(SUBAq, "SUBAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0));
REC_COP2_mVU0(SUBAx, "SUBAx", 0x4110);
REC_COP2_mVU0(SUBAy, "SUBAy", 0x4110);
REC_COP2_mVU0(SUBAz, "SUBAz", 0x4110);
REC_COP2_mVU0(SUBAw, "SUBAw", 0x4110);
REC_COP2_mVU0(MUL, "MUL", ((_cXYZW_SS2 || clampE) ? 0x2110 : 0x3110) + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MULi, "MULi", 0x2110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MULq, "MULq", 0x2111 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MULx, "MULx", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MULy, "MULy", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MULz, "MULz", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MULw, "MULw", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MULA, "MULA", 0x3110 + ((!_cXYZW_SS2 && !clampE && !_cXYZW_SS) ? 0x1000 : 0)); // Done
REC_COP2_mVU0(MULAi, "MULAi", 0x3110);
REC_COP2_mVU0(MULAq, "MULAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0));
REC_COP2_mVU0(MULAx, "MULAx", 0x4110);
REC_COP2_mVU0(MULAy, "MULAy", 0x4110);
REC_COP2_mVU0(MULAz, "MULAz", 0x4110);
REC_COP2_mVU0(MULAw, "MULAw", 0x4110);
REC_COP2_mVU0(MAX, "MAX", 0x3000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MAXi, "MAXi", 0x3000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MAXx, "MAXx", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MAXy, "MAXy", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MAXz, "MAXz", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MAXw, "MAXw", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MINI, "MINI", 0x3000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MINIi, "MINIi", 0x3000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MINIx, "MINIx", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MINIy, "MINIy", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MINIz, "MINIz", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MINIw, "MINIw", 0x4000 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MADD, "MADD", ((_cXYZW_SS2 || clampE) ? 0x3110 : 0x4110) + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MADDi, "MADDi", 0x3110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MADDq, "MADDq", 0x3111 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MADDx, "MADDx", 0x4110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MADDy, "MADDy", 0x4110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MADDz, "MADDz", 0x4110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MADDw, "MADDw", 0x4110 + (!_cXYZW_SS ? 0x1000 : 0));
REC_COP2_mVU0(MADDA, "MADDA", ((_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x3110 : 0x4110) + ((!_cXYZW_SS2 && !clampE && !_cXYZW_SS) ? 0x1000 : 0));
REC_COP2_mVU0(MADDAi, "MADDAi", 0x3110);
REC_COP2_mVU0(MADDAq, "MADDAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0) + (!(_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x1000 : 0));
REC_COP2_mVU0(MADDAx, "MADDAx", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110);
REC_COP2_mVU0(MADDAy, "MADDAy", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110);
REC_COP2_mVU0(MADDAz, "MADDAz", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110);
REC_COP2_mVU0(MADDAw, "MADDAw", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110);
REC_COP2_mVU0(MSUB, "MSUB", 0x3110 + ((!_cXYZW_SS && !clampE) ? 0x1000 : 0));
REC_COP2_mVU0(MSUBi, "MSUBi", 0x3110);
REC_COP2_mVU0(MSUBq, "MSUBq", 0x2111 + (!(_cXYZW_SS && !clampE) ? 0x1000 : 0));
REC_COP2_mVU0(MSUBx, "MSUBx", 0x4110);
REC_COP2_mVU0(MSUBy, "MSUBy", 0x4110);
REC_COP2_mVU0(MSUBz, "MSUBz", 0x4110);
REC_COP2_mVU0(MSUBw, "MSUBw", 0x4110);
REC_COP2_mVU0(MSUBA, "MSUBA", ((!(_cXYZW_SS2 || clampE) && !_cXYZW_SS) ? 0x4110 : 0x3110) + ((!_cXYZW_SS && _cX_Y_Z_W != 0xf) ? 0x1000 : 0));
REC_COP2_mVU0(MSUBAi, "MSUBAi", (!(_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x3110));
REC_COP2_mVU0(MSUBAq, "MSUBAq", 0x2111 + ((clampE || !_cXYZW_SS) ? 0x1000 : 0) + (!(_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x1000 : 0));
REC_COP2_mVU0(MSUBAx, "MSUBAx", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110);
REC_COP2_mVU0(MSUBAy, "MSUBAy", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110);
REC_COP2_mVU0(MSUBAz, "MSUBAz", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110);
REC_COP2_mVU0(MSUBAw, "MSUBAw", (_cXYZW_SS || _cX_Y_Z_W == 0xf) ? 0x4110 : 0x5110);
REC_COP2_mVU0(OPMULA, "OPMULA", 0x4110);
REC_COP2_mVU0(OPMSUB, "OPMSUB", 0x5110);
REC_COP2_mVU0(CLIP, "CLIP", 0x3108);
REC_COP2_mVU0(ABS, "ABS", 0x0);
REC_COP2_mVU0(ITOF0, "ITOF0", 0x0);
REC_COP2_mVU0(ITOF4, "ITOF4", 0x0);
REC_COP2_mVU0(ITOF12, "ITOF12", 0x0);
REC_COP2_mVU0(ITOF15, "ITOF15", 0x0);
REC_COP2_mVU0(FTOI0, "FTOI0", 0x0);
REC_COP2_mVU0(FTOI4, "FTOI4", 0x0);
REC_COP2_mVU0(FTOI12, "FTOI12", 0x0);
REC_COP2_mVU0(FTOI15, "FTOI15", 0x0);
REC_COP2_mVU0(ADD, "ADD", 0x110);
REC_COP2_mVU0(ADDi, "ADDi", 0x110);
REC_COP2_mVU0(ADDq, "ADDq", 0x111);
REC_COP2_mVU0(ADDx, "ADDx", 0x110);
REC_COP2_mVU0(ADDy, "ADDy", 0x110);
REC_COP2_mVU0(ADDz, "ADDz", 0x110);
REC_COP2_mVU0(ADDw, "ADDw", 0x110);
REC_COP2_mVU0(ADDA, "ADDA", 0x110);
REC_COP2_mVU0(ADDAi, "ADDAi", 0x110);
REC_COP2_mVU0(ADDAq, "ADDAq", 0x111);
REC_COP2_mVU0(ADDAx, "ADDAx", 0x110);
REC_COP2_mVU0(ADDAy, "ADDAy", 0x110);
REC_COP2_mVU0(ADDAz, "ADDAz", 0x110);
REC_COP2_mVU0(ADDAw, "ADDAw", 0x110);
REC_COP2_mVU0(SUB, "SUB", 0x110);
REC_COP2_mVU0(SUBi, "SUBi", 0x110);
REC_COP2_mVU0(SUBq, "SUBq", 0x111);
REC_COP2_mVU0(SUBx, "SUBx", 0x110);
REC_COP2_mVU0(SUBy, "SUBy", 0x110);
REC_COP2_mVU0(SUBz, "SUBz", 0x110);
REC_COP2_mVU0(SUBw, "SUBw", 0x110);
REC_COP2_mVU0(SUBA, "SUBA", 0x110);
REC_COP2_mVU0(SUBAi, "SUBAi", 0x110);
REC_COP2_mVU0(SUBAq, "SUBAq", 0x111);
REC_COP2_mVU0(SUBAx, "SUBAx", 0x110);
REC_COP2_mVU0(SUBAy, "SUBAy", 0x110);
REC_COP2_mVU0(SUBAz, "SUBAz", 0x110);
REC_COP2_mVU0(SUBAw, "SUBAw", 0x110);
REC_COP2_mVU0(MUL, "MUL", 0x110);
REC_COP2_mVU0(MULi, "MULi", 0x110);
REC_COP2_mVU0(MULq, "MULq", 0x111);
REC_COP2_mVU0(MULx, "MULx", 0x110);
REC_COP2_mVU0(MULy, "MULy", 0x110);
REC_COP2_mVU0(MULz, "MULz", 0x110);
REC_COP2_mVU0(MULw, "MULw", 0x110);
REC_COP2_mVU0(MULA, "MULA", 0x110);
REC_COP2_mVU0(MULAi, "MULAi", 0x110);
REC_COP2_mVU0(MULAq, "MULAq", 0x111);
REC_COP2_mVU0(MULAx, "MULAx", 0x110);
REC_COP2_mVU0(MULAy, "MULAy", 0x110);
REC_COP2_mVU0(MULAz, "MULAz", 0x110);
REC_COP2_mVU0(MULAw, "MULAw", 0x110);
REC_COP2_mVU0(MAX, "MAX", 0x0);
REC_COP2_mVU0(MAXi, "MAXi", 0x0);
REC_COP2_mVU0(MAXx, "MAXx", 0x0);
REC_COP2_mVU0(MAXy, "MAXy", 0x0);
REC_COP2_mVU0(MAXz, "MAXz", 0x0);
REC_COP2_mVU0(MAXw, "MAXw", 0x0);
REC_COP2_mVU0(MINI, "MINI", 0x0);
REC_COP2_mVU0(MINIi, "MINIi", 0x0);
REC_COP2_mVU0(MINIx, "MINIx", 0x0);
REC_COP2_mVU0(MINIy, "MINIy", 0x0);
REC_COP2_mVU0(MINIz, "MINIz", 0x0);
REC_COP2_mVU0(MINIw, "MINIw", 0x0);
REC_COP2_mVU0(MADD, "MADD", 0x110);
REC_COP2_mVU0(MADDi, "MADDi", 0x110);
REC_COP2_mVU0(MADDq, "MADDq", 0x111);
REC_COP2_mVU0(MADDx, "MADDx", 0x110);
REC_COP2_mVU0(MADDy, "MADDy", 0x110);
REC_COP2_mVU0(MADDz, "MADDz", 0x110);
REC_COP2_mVU0(MADDw, "MADDw", 0x110);
REC_COP2_mVU0(MADDA, "MADDA", 0x110);
REC_COP2_mVU0(MADDAi, "MADDAi", 0x110);
REC_COP2_mVU0(MADDAq, "MADDAq", 0x111);
REC_COP2_mVU0(MADDAx, "MADDAx", 0x110);
REC_COP2_mVU0(MADDAy, "MADDAy", 0x110);
REC_COP2_mVU0(MADDAz, "MADDAz", 0x110);
REC_COP2_mVU0(MADDAw, "MADDAw", 0x110);
REC_COP2_mVU0(MSUB, "MSUB", 0x110);
REC_COP2_mVU0(MSUBi, "MSUBi", 0x110);
REC_COP2_mVU0(MSUBq, "MSUBq", 0x111);
REC_COP2_mVU0(MSUBx, "MSUBx", 0x110);
REC_COP2_mVU0(MSUBy, "MSUBy", 0x110);
REC_COP2_mVU0(MSUBz, "MSUBz", 0x110);
REC_COP2_mVU0(MSUBw, "MSUBw", 0x110);
REC_COP2_mVU0(MSUBA, "MSUBA", 0x110);
REC_COP2_mVU0(MSUBAi, "MSUBAi", 0x110);
REC_COP2_mVU0(MSUBAq, "MSUBAq", 0x111);
REC_COP2_mVU0(MSUBAx, "MSUBAx", 0x110);
REC_COP2_mVU0(MSUBAy, "MSUBAy", 0x110);
REC_COP2_mVU0(MSUBAz, "MSUBAz", 0x110);
REC_COP2_mVU0(MSUBAw, "MSUBAw", 0x110);
REC_COP2_mVU0(OPMULA, "OPMULA", 0x110);
REC_COP2_mVU0(OPMSUB, "OPMSUB", 0x110);
REC_COP2_mVU0(CLIP, "CLIP", 0x108);
//------------------------------------------------------------------
// Macro VU - Redirect Lower Instructions
//------------------------------------------------------------------
REC_COP2_mVU0(DIV, "DIV", 0x3112);
REC_COP2_mVU0(SQRT, "SQRT", 0x1112);
REC_COP2_mVU0(RSQRT, "RSQRT", 0x3112);
REC_COP2_mVU0(DIV, "DIV", 0x112);
REC_COP2_mVU0(SQRT, "SQRT", 0x112);
REC_COP2_mVU0(RSQRT, "RSQRT", 0x112);
REC_COP2_mVU0(IADD, "IADD", 0x104);
REC_COP2_mVU0(IADDI, "IADDI", 0x104);
REC_COP2_mVU0(IAND, "IAND", 0x104);
@ -270,18 +266,18 @@ REC_COP2_mVU0(IOR, "IOR", 0x104);
REC_COP2_mVU0(ISUB, "ISUB", 0x104);
REC_COP2_mVU0(ILWR, "ILWR", 0x104);
REC_COP2_mVU0(ISWR, "ISWR", 0x100);
REC_COP2_mVU0(LQI, "LQI", 0x0104 + ((_Rt_) ? 0x1100 : 0));
REC_COP2_mVU0(LQD, "LQD", 0x0104 + ((_Rt_) ? 0x1100 : 0));
REC_COP2_mVU0(SQI, "SQI", 0x1100);
REC_COP2_mVU0(SQD, "SQD", 0x1100);
REC_COP2_mVU0(MFIR, "MFIR", 0x0104 + ((_Rt_) ? 0x1000 : 0));
REC_COP2_mVU0(MTIR, "MTIR", 0x0104 + (((cpuRegs.code >> 16) & 0xF) ? 0x1000 : 0)); // It
REC_COP2_mVU0(MOVE, "MOVE", 0x1000);
REC_COP2_mVU0(MR32, "MR32", 0x2000);
REC_COP2_mVU0(RINIT, "RINIT", 0x0100 + ((_Rd_ || (((cpuRegs.code >> 21) & 0x03) == 3)) ? 0x1000 : 0)); //Fsf
REC_COP2_mVU0(RGET, "RGET", 0x0104 + (_Rt_ != 0 ? 0x1000 : 0));
REC_COP2_mVU0(RNEXT, "RNEXT", 0x0104 + (_Rt_ != 0 ? 0x1000 : 0));
REC_COP2_mVU0(RXOR, "RXOR", 0x0100 + ((_Rd_ || (((cpuRegs.code >> 21) & 0x03) == 3)) ? 0x1000 : 0)); //Fsf
REC_COP2_mVU0(LQI, "LQI", 0x104);
REC_COP2_mVU0(LQD, "LQD", 0x104);
REC_COP2_mVU0(SQI, "SQI", 0x100);
REC_COP2_mVU0(SQD, "SQD", 0x100);
REC_COP2_mVU0(MFIR, "MFIR", 0x104);
REC_COP2_mVU0(MTIR, "MTIR", 0x104);
REC_COP2_mVU0(MOVE, "MOVE", 0x0);
REC_COP2_mVU0(MR32, "MR32", 0x0);
REC_COP2_mVU0(RINIT, "RINIT", 0x100);
REC_COP2_mVU0(RGET, "RGET", 0x104);
REC_COP2_mVU0(RNEXT, "RNEXT", 0x104);
REC_COP2_mVU0(RXOR, "RXOR", 0x100);
//------------------------------------------------------------------
// Macro VU - Misc...