[ARM] Reimplement fastmem for the few loadstores that had it before.

This commit is contained in:
Ryan Houdek 2013-09-04 02:07:48 +00:00
parent e9ffba7ab8
commit 8684b7635a
3 changed files with 59 additions and 44 deletions

View File

@ -296,6 +296,7 @@ void STACKALIGN JitArm::Jit(u32 em_address)
}
void JitArm::Break(UGeckoInstruction inst)
{
ERROR_LOG(DYNA_REC, "%s called a Break instruction!", PPCTables::GetInstructionName(inst));
BKPT(0x4444);
}

View File

@ -127,8 +127,8 @@ public:
void UnsafeStoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset);
void SafeStoreFromReg(bool fastmem, s32 dest, u32 value, s32 offsetReg, int accessSize, s32 offset);
void SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse);
void LoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset);
void UnsafeLoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset);
void SafeLoadToReg(bool fastmem, u32 dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse);
// OPCODES

View File

@ -217,9 +217,58 @@ void JitArm::stX(UGeckoInstruction inst)
}
}
void JitArm::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse)
void JitArm::UnsafeLoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset)
{
ARMReg rA = gpr.GetReg();
MOVI2R(rA, offset, false); // -3
ADD(addr, addr, rA); // - 1
// All this gets replaced on backpatch
MOVI2R(rA, Memory::MEMVIEW32_MASK, false); // 2
AND(addr, addr, rA); // 3
MOVI2R(rA, (u32)Memory::base, false); // 5
ADD(addr, addr, rA); // 6
switch (accessSize)
{
case 32:
LDR(dest, addr); // 7
break;
case 16:
LDRH(dest, addr);
break;
case 8:
LDRB(dest, addr);
break;
}
switch (accessSize)
{
case 32:
REV(dest, dest); // 9
break;
case 16:
REV16(dest, dest);
break;
case 8:
NOP(1);
break;
}
gpr.Unlock(rA);
}
void JitArm::SafeLoadToReg(bool fastmem, u32 dest, s32 addr, s32 offsetReg, int accessSize, s32 offset, bool signExtend, bool reverse)
{
ARMReg RD = gpr.R(dest);
if (Core::g_CoreStartupParameter.bFastmem && fastmem)
{
if (addr != -1)
MOV(R10, gpr.R(addr));
else
MOV(R10, 0);
UnsafeLoadToReg(RD, R10, accessSize, offset);
return;
}
ARMReg rA = gpr.GetReg();
ARMReg rB = gpr.GetReg();
@ -273,7 +322,8 @@ void JitArm::lXX(UGeckoInstruction inst)
bool update = false;
bool signExtend = false;
bool reverse = false;
bool fastmem = false;
switch(inst.OPCD)
{
case 31:
@ -322,18 +372,21 @@ void JitArm::lXX(UGeckoInstruction inst)
zeroA = false;
update = true;
case 32: // lwz
fastmem = true;
accessSize = 32;
break;
case 35: // lbzu
zeroA = false;
update = true;
case 34: // lbz
fastmem = true;
accessSize = 8;
break;
case 41: // lhzu
zeroA = false;
update = true;
case 40: // lhz
fastmem = true;
accessSize = 16;
break;
case 43: // lhau
@ -351,7 +404,7 @@ void JitArm::lXX(UGeckoInstruction inst)
CMP(rA, EXCEPTION_DSI);
FixupBranch DoNotLoad = B_CC(CC_EQ);
SafeLoadToReg(d, zeroA ? a ? a : -1 : a, offsetReg, accessSize, offset, signExtend, reverse);
SafeLoadToReg(fastmem, d, zeroA ? a ? a : -1 : a, offsetReg, accessSize, offset, signExtend, reverse);
if (update)
{
@ -397,45 +450,6 @@ void JitArm::lXX(UGeckoInstruction inst)
}
void JitArm::LoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset)
{
ARMReg rA = gpr.GetReg();
MOVI2R(rA, offset, false); // -3
ADD(addr, addr, rA); // - 1
// All this gets replaced on backpatch
MOVI2R(rA, Memory::MEMVIEW32_MASK, false); // 2
AND(addr, addr, rA); // 3
MOVI2R(rA, (u32)Memory::base, false); // 5
ADD(addr, addr, rA); // 6
switch (accessSize)
{
case 32:
LDR(dest, addr); // 7
break;
case 16:
LDRH(dest, addr);
break;
case 8:
LDRB(dest, addr);
break;
}
switch (accessSize)
{
case 32:
REV(dest, dest); // 9
break;
case 16:
REV16(dest, dest);
break;
case 8:
NOP(1);
break;
}
gpr.Unlock(rA);
}
// Some games use this heavily in video codecs
// We make the assumption that this pulls from main RAM at /all/ times
void JitArm::lmw(UGeckoInstruction inst)