Make swc1 and lwc1 fast even without fastmem.

This commit is contained in:
Unknown W. Brackets committed 2013-01-20 02:07:00 -08:00
1 parent 2cb830510c
commit da22eb8adf
1 file changed
+117 -17
+117 -17
View File
@@ -84,18 +84,14 @@ void Jit::Comp_FPU3op(u32 op)
}
}
static u32 GC_ALIGNED16(ssLoadStoreTemp[1]);
void Jit::Comp_FPULS(u32 op)
{
CONDITIONAL_DISABLE;
if (!g_Config.bFastMemory) {
DISABLE;
}
s32 offset = (s16)(op&0xFFFF);
int ft = ((op>>16)&0x1f);
int ft = _FT;
int rs = _RS;
// u32 addr = R(rs) + offset;
switch(op >> 26)
{
@@ -103,14 +99,69 @@ void Jit::Comp_FPULS(u32 op)
gpr.Lock(rs);
fpr.Lock(ft);
fpr.BindToRegister(ft, false, true);
if (gpr.R(rs).IsImm())
{
void *data = Memory::GetPointer(gpr.R(rs).GetImmValue() + offset);
if (data)
{
#ifdef _M_IX86
MOV(32, R(EAX), gpr.R(rs));
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
MOVSS(fpr.RX(ft), MDisp(EAX, (u32)Memory::base + offset));
MOVSS(fpr.RX(ft), M(data));
#else
MOV(32, R(EAX), gpr.R(rs));
MOVSS(fpr.RX(ft), MComplex(RBX, RAX, SCALE_1, offset));
MOVSS(fpr.RX(ft), MDisp(RBX, gpr.R(rs).GetImmValue() + offset));
#endif
}
else
{
MOV(32, M((void *)ssLoadStoreTemp), Imm32(0));
MOVSS(fpr.RX(ft), M((void *)ssLoadStoreTemp));
}
}
else if (!g_Config.bFastMemory)
{
MOV(32, R(EAX), gpr.R(rs));
// Is it in physical ram?
CMP(32, R(EAX), Imm32(0x08000000));
FixupBranch tooLow = J_CC(CC_L);
CMP(32, R(EAX), Imm32(0x0A000000));
FixupBranch tooHigh = J_CC(CC_GE);
const u8* safe = GetCodePtr();
#ifdef _M_IX86
MOVSS(fpr.RX(ft), MDisp(EAX, (u32)Memory::base + offset));
#else
MOVSS(fpr.RX(ft), MComplex(RBX, RAX, SCALE_1, offset));
#endif
FixupBranch skip = J();
SetJumpTarget(tooLow);
SetJumpTarget(tooHigh);
// Might also be the scratchpad.
CMP(32, R(EAX), Imm32(0x00010000));
FixupBranch tooLow2 = J_CC(CC_L);
CMP(32, R(EAX), Imm32(0x00014000));
J_CC(CC_L, safe);
SetJumpTarget(tooLow2);
ADD(32, R(EAX), Imm32(offset));
ABI_CallFunctionA(thunks.ProtectFunction((void *) &Memory::Read_U32, 1), R(EAX));
MOV(32, M((void *)&ssLoadStoreTemp), R(EAX));
MOVSS(fpr.RX(ft), M((void *)&ssLoadStoreTemp));
SetJumpTarget(skip);
}
else
{
MOV(32, R(EAX), gpr.R(rs));
#ifdef _M_IX86
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
MOVSS(fpr.RX(ft), MDisp(EAX, (u32)Memory::base + offset));
#else
MOVSS(fpr.RX(ft), MComplex(RBX, RAX, SCALE_1, offset));
#endif
}
gpr.UnlockAll();
fpr.UnlockAll();
break;
@@ -118,14 +169,63 @@ void Jit::Comp_FPULS(u32 op)
gpr.Lock(rs);
fpr.Lock(ft);
fpr.BindToRegister(ft, true, false);
if (gpr.R(rs).IsImm())
{
void *data = Memory::GetPointer(gpr.R(rs).GetImmValue() + offset);
if (data)
{
#ifdef _M_IX86
MOV(32, R(EAX), gpr.R(rs));
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
MOVSS(MDisp(EAX, (u32)Memory::base + offset), fpr.RX(ft));
MOVSS(M(data), fpr.RX(ft));
#else
MOV(32, R(EAX), gpr.R(rs));
MOVSS(MComplex(RBX, RAX, SCALE_1, offset), fpr.RX(ft));
MOVSS(MDisp(RBX, gpr.R(rs).GetImmValue() + offset), fpr.RX(ft));
#endif
}
}
else if (!g_Config.bFastMemory)
{
MOV(32, R(EAX), gpr.R(rs));
// Is it in physical ram?
CMP(32, R(EAX), Imm32(0x08000000));
FixupBranch tooLow = J_CC(CC_L);
CMP(32, R(EAX), Imm32(0x0A000000));
FixupBranch tooHigh = J_CC(CC_GE);
const u8* safe = GetCodePtr();
#ifdef _M_IX86
MOVSS(MDisp(EAX, (u32)Memory::base + offset), fpr.RX(ft));
#else
MOVSS(MComplex(RBX, RAX, SCALE_1, offset), fpr.RX(ft));
#endif
FixupBranch skip = J();
SetJumpTarget(tooLow);
SetJumpTarget(tooHigh);
// Might also be the scratchpad.
CMP(32, R(EAX), Imm32(0x00010000));
FixupBranch tooLow2 = J_CC(CC_L);
CMP(32, R(EAX), Imm32(0x00014000));
J_CC(CC_L, safe);
SetJumpTarget(tooLow2);
ADD(32, R(EAX), Imm32(offset));
MOVSS(M((void *)&ssLoadStoreTemp), fpr.RX(ft));
ABI_CallFunctionAA(thunks.ProtectFunction((void *) &Memory::Write_U32, 2), M((void *)&ssLoadStoreTemp), R(EAX));
SetJumpTarget(skip);
}
else
{
MOV(32, R(EAX), gpr.R(rs));
#ifdef _M_IX86
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
MOVSS(MDisp(EAX, (u32)Memory::base + offset), fpr.RX(ft));
#else
MOVSS(MComplex(RBX, RAX, SCALE_1, offset), fpr.RX(ft));
#endif
}
gpr.UnlockAll();
fpr.UnlockAll();
break;