Optimize sw/lw even under safe memory.

They're very common instructions, so shaving cycles helps.
This commit is contained in:
Unknown W. Brackets 2013-01-18 08:30:28 -08:00
parent faf4b76bbb
commit d5ae85201c
3 changed files with 59 additions and 13 deletions

View File

@ -160,6 +160,16 @@ void XEmitter::ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2
ABI_RestoreStack(2 * 4);
}
void XEmitter::ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param2, u32 param3)
{
ABI_AlignStack(3 * 4);
PUSH(32, Imm32(param3));
PUSH(32, Imm32(param2));
PUSH(32, arg1);
CALL(func);
ABI_RestoreStack(3 * 4);
}
void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
{
ABI_AlignStack(1 * 4);
@ -404,6 +414,22 @@ void XEmitter::ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2
}
}
void XEmitter::ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param2, u32 param3)
{
MOV(32, R(ABI_PARAM1), arg1);
MOV(32, R(ABI_PARAM2), Imm32(param2));
MOV(64, R(ABI_PARAM3), Imm64(param3));
u64 distance = u64(func) - (u64(code) + 5);
if (distance >= 0x0000000080000000ULL
&& distance < 0xFFFFFFFF80000000ULL) {
// Far call
MOV(64, R(RAX), Imm64((u64)func));
CALLptr(R(RAX));
} else {
CALL(func);
}
}
void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
{
if (!arg1.IsSimpleReg(ABI_PARAM1))

View File

@ -656,6 +656,7 @@ public:
void ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2,u32 param3, void *param4);
void ABI_CallFunctionPPC(void *func, void *param1, void *param2,u32 param3);
void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2);
void ABI_CallFunctionACC(void *func, const Gen::OpArg &arg1, u32 param2, u32 param3);
void ABI_CallFunctionA(void *func, const Gen::OpArg &arg1);
// Pass a register as a paremeter.

View File

@ -41,13 +41,18 @@
namespace MIPSComp
{
void ReadMemSafe(u32 addr, int preg, u32 offset)
{
currentMIPS->r[preg] = Memory::Read_U32(addr + offset);
}
void WriteMemSafe(u32 addr, int preg, u32 offset)
{
Memory::Write_U32(currentMIPS->r[preg], addr + offset);
}
void Jit::Comp_ITypeMem(u32 op)
{
if (!g_Config.bFastMemory)
{
DISABLE;
}
int offset = (signed short)(op&0xFFFF);
int rt = _RT;
int rs = _RS;
@ -65,17 +70,25 @@ namespace MIPSComp
return;
case 35: //R(rt) = ReadMem32(addr); break; //lw
gpr.Lock(rt, rs);
gpr.BindToRegister(rt, rt == rs, true);
if (!g_Config.bFastMemory)
{
FlushAll();
ABI_CallFunctionACC((void *) &ReadMemSafe, gpr.R(rs), rt, offset);
}
else
{
gpr.Lock(rt, rs);
gpr.BindToRegister(rt, rt == rs, true);
#ifdef _M_IX86
MOV(32, R(EAX), gpr.R(rs));
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
MOV(32, gpr.R(rt), MDisp(EAX, (u32)Memory::base + offset));
MOV(32, R(EAX), gpr.R(rs));
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
MOV(32, gpr.R(rt), MDisp(EAX, (u32)Memory::base + offset));
#else
MOV(32, R(EAX), gpr.R(rs));
MOV(32, gpr.R(rt), MComplex(RBX, EAX, SCALE_1, offset));
MOV(32, R(EAX), gpr.R(rs));
MOV(32, gpr.R(rt), MComplex(RBX, EAX, SCALE_1, offset));
#endif
gpr.UnlockAll();
gpr.UnlockAll();
}
break;
case 132: //R(rt) = (u32)(s32)(s8) ReadMem8 (addr); break; //lb
@ -89,6 +102,12 @@ namespace MIPSComp
return;
case 43: //WriteMem32(addr, R(rt)); break; //sw
if (!g_Config.bFastMemory)
{
FlushAll();
ABI_CallFunctionACC((void *) &WriteMemSafe, gpr.R(rs), rt, offset);
}
else
{
gpr.Lock(rt, rs);
gpr.BindToRegister(rt, true, false);