Some JIT cleanup. Have not been able to figure out the "dirty-flag" mystery yet :(
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1269 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
3e7c80ab69
commit
117a05fa64
|
@ -96,7 +96,7 @@ namespace Jit64
|
|||
|
||||
void RegCache::UnlockAllX()
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
for (int i = 0; i < NUMXREGS; i++)
|
||||
xlocks[i] = false;
|
||||
}
|
||||
|
||||
|
@ -175,24 +175,6 @@ namespace Jit64
|
|||
}
|
||||
}
|
||||
|
||||
bool GPRRegCache::IsXRegVolatile(X64Reg reg) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
switch (reg)
|
||||
{
|
||||
case RAX: case RCX: case RDX: case R8: case R9: case R10: case R11:
|
||||
#ifdef _M_IX86
|
||||
case RBX:
|
||||
#endif
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void RegCache::DiscardRegContentsIfCached(int preg)
|
||||
{
|
||||
if (regs[preg].away && regs[preg].location.IsSimpleReg())
|
||||
|
@ -211,23 +193,11 @@ namespace Jit64
|
|||
regs[preg].location = Imm32(immValue);
|
||||
}
|
||||
|
||||
bool FPURegCache::IsXRegVolatile(X64Reg reg) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// return true;
|
||||
if (reg < 6)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GPRRegCache::Start(PPCAnalyst::BlockRegStats &stats)
|
||||
{
|
||||
RegCache::Start(stats);
|
||||
}
|
||||
|
||||
void FPURegCache::Start(PPCAnalyst::BlockRegStats &stats)
|
||||
{
|
||||
RegCache::Start(stats);
|
||||
|
@ -275,20 +245,23 @@ namespace Jit64
|
|||
return M(&ppcState.ps[reg][0]);
|
||||
}
|
||||
|
||||
// eheh, this was a dupe.
|
||||
void RegCache::KillImmediate(int preg)
|
||||
{
|
||||
if (regs[preg].away && regs[preg].location.IsImm())
|
||||
{
|
||||
StoreFromX64(preg);
|
||||
LoadToX64(preg, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void GPRRegCache::LoadToX64(int i, bool doLoad, bool makeDirty)
|
||||
{
|
||||
if (!regs[i].away && regs[i].location.IsImm())
|
||||
PanicAlert("Bad immedaite");
|
||||
|
||||
if (!regs[i].away || (regs[i].away && regs[i].location.IsImm()))
|
||||
{
|
||||
X64Reg xr = GetFreeXReg();
|
||||
if (xregs[xr].dirty) PanicAlert("Xreg already dirty");
|
||||
if (xlocks[xr]) PanicAlert("GetFreeXReg returned locked register");
|
||||
xregs[xr].free = false;
|
||||
xregs[xr].ppcReg = i;
|
||||
|
@ -310,8 +283,10 @@ namespace Jit64
|
|||
{
|
||||
// HERE HOLDS: regs[i].away == true
|
||||
//
|
||||
//reg location must be simplereg
|
||||
xregs[RX(i)].dirty |= makeDirty;
|
||||
//reg location must be simplereg or immediate
|
||||
if (regs[i].location.IsSimpleReg()) {
|
||||
xregs[RX(i)].dirty |= makeDirty;
|
||||
}
|
||||
}
|
||||
if (xlocks[RX(i)]) {
|
||||
PanicAlert("Seriously WTF, this reg should have been flushed");
|
||||
|
@ -322,7 +297,7 @@ namespace Jit64
|
|||
{
|
||||
if (regs[i].away)
|
||||
{
|
||||
bool doStore = true;
|
||||
bool doStore;
|
||||
if (regs[i].location.IsSimpleReg())
|
||||
{
|
||||
X64Reg xr = RX(i);
|
||||
|
@ -334,10 +309,10 @@ namespace Jit64
|
|||
else
|
||||
{
|
||||
//must be immediate - do nothing
|
||||
doStore = true;
|
||||
}
|
||||
OpArg newLoc = GetDefaultLocation(i);
|
||||
|
||||
//if (doStore) <-- Breaks JIT compilation
|
||||
// if (doStore) //<-- Breaks JIT compilation
|
||||
MOV(32, newLoc, regs[i].location);
|
||||
regs[i].location = newLoc;
|
||||
regs[i].away = false;
|
||||
|
@ -349,6 +324,7 @@ namespace Jit64
|
|||
_assert_msg_(DYNA_REC, !regs[i].location.IsImm(), "WTF - load - imm");
|
||||
if (!regs[i].away)
|
||||
{
|
||||
// Reg is at home in the memory register file. Let's pull it out.
|
||||
X64Reg xr = GetFreeXReg();
|
||||
_assert_msg_(DYNA_REC, xr >= 0 && xr < NUMXREGS, "WTF - load - invalid reg");
|
||||
xregs[xr].ppcReg = i;
|
||||
|
@ -363,6 +339,9 @@ namespace Jit64
|
|||
}
|
||||
regs[i].location = newloc;
|
||||
regs[i].away = true;
|
||||
} else {
|
||||
// There are no immediates in the FPR reg file, so we already had this in a register. Make dirty as necessary.
|
||||
xregs[RX(i)].dirty |= makeDirty;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -389,11 +368,15 @@ namespace Jit64
|
|||
|
||||
void RegCache::Flush(FlushMode mode)
|
||||
{
|
||||
for (int i = 0; i < NUMXREGS; i++) {
|
||||
if (xlocks[i])
|
||||
PanicAlert("Somone forgot to unlock X64 reg %i.", i);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if (locks[i])
|
||||
{
|
||||
_assert_msg_(DYNA_REC,0,"Somebody forgot some register locks.");
|
||||
PanicAlert("Somebody forgot to unlock PPC reg %i.", i);
|
||||
}
|
||||
if (regs[i].away)
|
||||
{
|
||||
|
|
|
@ -64,9 +64,9 @@ namespace Jit64
|
|||
private:
|
||||
bool locks[32];
|
||||
bool saved_locks[32];
|
||||
bool saved_xlocks[16];
|
||||
bool saved_xlocks[NUMXREGS];
|
||||
protected:
|
||||
bool xlocks[16];
|
||||
bool xlocks[NUMXREGS];
|
||||
PPCCachedReg regs[32];
|
||||
X64CachedReg xregs[NUMXREGS];
|
||||
|
||||
|
@ -102,7 +102,7 @@ namespace Jit64
|
|||
{
|
||||
if (regs[preg].away && regs[preg].location.IsSimpleReg())
|
||||
return regs[preg].location.GetSimpleReg();
|
||||
_assert_msg_(DYNA_REC,0,"Not so simple");
|
||||
PanicAlert("Not so simple - %i", preg);
|
||||
return (X64Reg)-1;
|
||||
}
|
||||
virtual OpArg GetDefaultLocation(int reg) const = 0;
|
||||
|
@ -115,9 +115,6 @@ namespace Jit64
|
|||
bool IsFreeX(int xreg) const;
|
||||
|
||||
X64Reg GetFreeXReg();
|
||||
int GetNumXRegs(){return 16;}
|
||||
|
||||
virtual bool IsXRegVolatile(X64Reg reg) const = 0;
|
||||
|
||||
void SaveState();
|
||||
void LoadState();
|
||||
|
@ -131,7 +128,6 @@ namespace Jit64
|
|||
void StoreFromX64(int preg);
|
||||
OpArg GetDefaultLocation(int reg) const;
|
||||
const int *GetAllocationOrder(int &count);
|
||||
bool IsXRegVolatile(X64Reg reg) const;
|
||||
void SetImmediate32(int preg, u32 immValue);
|
||||
};
|
||||
|
||||
|
@ -143,7 +139,6 @@ namespace Jit64
|
|||
void LoadToX64(int preg, bool doLoad = true, bool makeDirty = true);
|
||||
void StoreFromX64(int preg);
|
||||
const int *GetAllocationOrder(int &count);
|
||||
bool IsXRegVolatile(X64Reg reg) const;
|
||||
OpArg GetDefaultLocation(int reg) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -373,7 +373,6 @@ namespace Jit64
|
|||
int a = inst.RA,
|
||||
s = inst.RS;
|
||||
gpr.LoadToX64(a, a == s, true);
|
||||
gpr.KillImmediate(s);
|
||||
MOV(32, R(EAX), gpr.R(s));
|
||||
MOVSX(32, 8, gpr.RX(a), R(AL)); // watch out for ah and friends
|
||||
if (inst.Rc) {
|
||||
|
@ -391,8 +390,8 @@ namespace Jit64
|
|||
INSTRUCTION_START;
|
||||
int a = inst.RA, s = inst.RS;
|
||||
gpr.LoadToX64(a, a == s, true);
|
||||
gpr.KillImmediate(s);
|
||||
MOVSX(32, 16, gpr.RX(a), gpr.R(s));
|
||||
MOV(32, R(EAX), gpr.R(s));
|
||||
MOVSX(32, 16, gpr.RX(a), R(EAX));
|
||||
if (inst.Rc) {
|
||||
MOV(32, R(EAX), gpr.R(a));
|
||||
CALL((u8*)Asm::computeRc);
|
||||
|
|
|
@ -73,14 +73,14 @@ namespace Jit64
|
|||
ADD(32, R(ABI_PARAM1), gpr.R(a));
|
||||
#if 0
|
||||
SafeLoadRegToEAX(ABI_PARAM1, 8, 0);
|
||||
MOV(32, gpr.R(d), R(EAX));
|
||||
#else
|
||||
MOV(32, gpr.R(d), R(EAX));
|
||||
#else
|
||||
UnsafeLoadRegToReg(ABI_PARAM1, gpr.RX(d), 8, 0, false);
|
||||
#endif
|
||||
gpr.UnlockAll();
|
||||
gpr.UnlockAllX();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void lwzx(UGeckoInstruction inst)
|
||||
{
|
||||
#ifdef JIT_OFF_OPTIONS
|
||||
|
@ -98,17 +98,17 @@ namespace Jit64
|
|||
gpr.LoadToX64(d, false, true);
|
||||
MOV(32, R(ABI_PARAM1), gpr.R(b));
|
||||
if (a)
|
||||
ADD(32, R(ABI_PARAM1), gpr.R(a));
|
||||
ADD(32, R(ABI_PARAM1), gpr.R(a));
|
||||
#if 1
|
||||
SafeLoadRegToEAX(ABI_PARAM1, 32, 0);
|
||||
MOV(32, gpr.R(d), R(EAX));
|
||||
#else
|
||||
UnsafeLoadRegToReg(ABI_PARAM1, gpr.RX(d), 32, 0, false);
|
||||
MOV(32, gpr.R(d), R(EAX));
|
||||
#else
|
||||
UnsafeLoadRegToReg(ABI_PARAM1, gpr.RX(d), 32, 0, false);
|
||||
#endif
|
||||
gpr.UnlockAll();
|
||||
gpr.UnlockAllX();
|
||||
}
|
||||
|
||||
|
||||
void lhax(UGeckoInstruction inst)
|
||||
{
|
||||
#ifdef JIT_OFF_OPTIONS
|
||||
|
@ -126,12 +126,12 @@ namespace Jit64
|
|||
gpr.LoadToX64(d, false, true);
|
||||
MOV(32, R(ABI_PARAM1), gpr.R(b));
|
||||
if (a)
|
||||
ADD(32, R(ABI_PARAM1), gpr.R(a));
|
||||
ADD(32, R(ABI_PARAM1), gpr.R(a));
|
||||
#if 1
|
||||
SafeLoadRegToEAX(ABI_PARAM1, 16, 0, true);
|
||||
MOV(32, gpr.R(d), R(EAX));
|
||||
#else
|
||||
UnsafeLoadRegToReg(ABI_PARAM1, gpr.RX(d), 16, 0, true);
|
||||
MOV(32, gpr.R(d), R(EAX));
|
||||
#else
|
||||
UnsafeLoadRegToReg(ABI_PARAM1, gpr.RX(d), 16, 0, true);
|
||||
#endif
|
||||
gpr.UnlockAll();
|
||||
gpr.UnlockAllX();
|
||||
|
@ -339,8 +339,6 @@ namespace Jit64
|
|||
BSWAP(accessSize, EAX);
|
||||
WriteToConstRamAddress(accessSize, R(EAX), addr);
|
||||
return;
|
||||
// PanicAlert("yum yum");
|
||||
// This may be quite beneficial.
|
||||
}
|
||||
// Other IO not worth the trouble.
|
||||
}
|
||||
|
|
|
@ -134,6 +134,7 @@ void psq_st(UGeckoInstruction inst)
|
|||
{
|
||||
case QUANTIZE_FLOAT:
|
||||
{
|
||||
// This one has quite a bit of optimization potential.
|
||||
if (gpr.R(a).IsImm())
|
||||
{
|
||||
PanicAlert("Imm: %08x", gpr.R(a).offset);
|
||||
|
@ -216,7 +217,7 @@ void psq_st(UGeckoInstruction inst)
|
|||
CALL(ProtectFunction((void *)&WriteDual32, 0));
|
||||
#else
|
||||
FixupBranch argh = J_CC(CC_NZ);
|
||||
MOV(32, R(ABI_PARAM1), M(((char*)&temp64)+4));
|
||||
MOV(32, R(ABI_PARAM1), M(((char*)&temp64) + 4));
|
||||
BSWAP(32, ABI_PARAM1);
|
||||
AND(32, R(ABI_PARAM2), Imm32(Memory::MEMVIEW32_MASK));
|
||||
MOV(32, MDisp(ABI_PARAM2, (u32)Memory::base), R(ABI_PARAM1));
|
||||
|
@ -225,7 +226,7 @@ void psq_st(UGeckoInstruction inst)
|
|||
MOV(32, MDisp(ABI_PARAM2, 4+(u32)Memory::base), R(ABI_PARAM1));
|
||||
FixupBranch arg2 = J();
|
||||
SetJumpTarget(argh);
|
||||
MOV(32, R(ABI_PARAM1), M(((char*)&temp64)+4));
|
||||
MOV(32, R(ABI_PARAM1), M(((char*)&temp64) + 4));
|
||||
ABI_CallFunctionRR(ProtectFunction((void *)&Memory::Write_U32, 2), ABI_PARAM1, ABI_PARAM2);
|
||||
MOV(32, R(ABI_PARAM1), M(((char*)&temp64)));
|
||||
ADD(32, R(ABI_PARAM2), Imm32(4));
|
||||
|
@ -370,7 +371,7 @@ void psq_l(UGeckoInstruction inst)
|
|||
CVTPS2PD(xd, R(xd));
|
||||
} else {
|
||||
gpr.FlushLockX(ECX);
|
||||
gpr.LoadToX64(inst.RA);
|
||||
gpr.LoadToX64(inst.RA, true, update);
|
||||
// This can probably be optimized somewhat.
|
||||
LEA(32, ECX, MDisp(gpr.R(inst.RA).GetSimpleReg(), offset));
|
||||
AND(32, R(ECX), Imm32(Memory::MEMVIEW32_MASK));
|
||||
|
@ -380,7 +381,7 @@ void psq_l(UGeckoInstruction inst)
|
|||
MOV(32, R(EAX), MDisp(ECX, (u32)Memory::base + 4));
|
||||
BSWAP(32, RAX);
|
||||
MOV(32, M(((float *)&psTemp[0]) + 1), R(RAX));
|
||||
fpr.LoadToX64(inst.RS, false);
|
||||
fpr.LoadToX64(inst.RS, false, true);
|
||||
X64Reg r = fpr.R(inst.RS).GetSimpleReg();
|
||||
CVTPS2PD(r, M(&psTemp[0]));
|
||||
gpr.UnlockAllX();
|
||||
|
@ -392,7 +393,7 @@ void psq_l(UGeckoInstruction inst)
|
|||
}
|
||||
case QUANTIZE_U8:
|
||||
{
|
||||
gpr.LoadToX64(inst.RA);
|
||||
gpr.LoadToX64(inst.RA, true, update);
|
||||
#ifdef _M_X64
|
||||
MOVZX(32, 16, EAX, MComplex(RBX, gpr.R(inst.RA).GetSimpleReg(), 1, offset));
|
||||
#else
|
||||
|
@ -407,7 +408,7 @@ void psq_l(UGeckoInstruction inst)
|
|||
PUNPCKLBW(XMM0, R(XMM1));
|
||||
PUNPCKLWD(XMM0, R(XMM1));
|
||||
CVTDQ2PD(XMM0, R(XMM0));
|
||||
fpr.LoadToX64(inst.RS, false);
|
||||
fpr.LoadToX64(inst.RS, false, true);
|
||||
X64Reg r = fpr.R(inst.RS).GetSimpleReg();
|
||||
MOVDDUP(r, M((void *)&m_dequantizeTableD[ldScale]));
|
||||
MULPD(r, R(XMM0));
|
||||
|
@ -417,7 +418,7 @@ void psq_l(UGeckoInstruction inst)
|
|||
break;
|
||||
case QUANTIZE_S16:
|
||||
{
|
||||
gpr.LoadToX64(inst.RA);
|
||||
gpr.LoadToX64(inst.RA, true, update);
|
||||
#ifdef _M_X64
|
||||
MOV(32, R(EAX), MComplex(RBX, gpr.R(inst.RA).GetSimpleReg(), 1, offset));
|
||||
#else
|
||||
|
@ -428,7 +429,7 @@ void psq_l(UGeckoInstruction inst)
|
|||
BSWAP(32, EAX);
|
||||
MOV(32, M(&temp64), R(EAX));
|
||||
//INT3();
|
||||
fpr.LoadToX64(inst.RS, false);
|
||||
fpr.LoadToX64(inst.RS, false, true);
|
||||
X64Reg r = fpr.R(inst.RS).GetSimpleReg();
|
||||
MOVD_xmm(XMM0, M(&temp64));
|
||||
PUNPCKLWD(XMM0, R(XMM0)); // unpack to higher word in each dword..
|
||||
|
|
Loading…
Reference in New Issue