mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-27 00:05:34 +01:00
[ARM] Reimplement fastmem for the few loadstores that had it before.
This commit is contained in:
parent
e9ffba7ab8
commit
8684b7635a
@ -296,6 +296,7 @@ void STACKALIGN JitArm::Jit(u32 em_address)
|
|||||||
}
|
}
|
||||||
void JitArm::Break(UGeckoInstruction inst)
|
void JitArm::Break(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
ERROR_LOG(DYNA_REC, "%s called a Break instruction!", PPCTables::GetInstructionName(inst));
|
||||||
BKPT(0x4444);
|
BKPT(0x4444);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,8 +127,8 @@ public:
|
|||||||
void UnsafeStoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset);
|
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 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 UnsafeLoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset);
|
||||||
void LoadToReg(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
|
// OPCODES
|
||||||
|
@ -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);
|
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 rA = gpr.GetReg();
|
||||||
ARMReg rB = gpr.GetReg();
|
ARMReg rB = gpr.GetReg();
|
||||||
|
|
||||||
@ -273,6 +322,7 @@ void JitArm::lXX(UGeckoInstruction inst)
|
|||||||
bool update = false;
|
bool update = false;
|
||||||
bool signExtend = false;
|
bool signExtend = false;
|
||||||
bool reverse = false;
|
bool reverse = false;
|
||||||
|
bool fastmem = false;
|
||||||
|
|
||||||
switch(inst.OPCD)
|
switch(inst.OPCD)
|
||||||
{
|
{
|
||||||
@ -322,18 +372,21 @@ void JitArm::lXX(UGeckoInstruction inst)
|
|||||||
zeroA = false;
|
zeroA = false;
|
||||||
update = true;
|
update = true;
|
||||||
case 32: // lwz
|
case 32: // lwz
|
||||||
|
fastmem = true;
|
||||||
accessSize = 32;
|
accessSize = 32;
|
||||||
break;
|
break;
|
||||||
case 35: // lbzu
|
case 35: // lbzu
|
||||||
zeroA = false;
|
zeroA = false;
|
||||||
update = true;
|
update = true;
|
||||||
case 34: // lbz
|
case 34: // lbz
|
||||||
|
fastmem = true;
|
||||||
accessSize = 8;
|
accessSize = 8;
|
||||||
break;
|
break;
|
||||||
case 41: // lhzu
|
case 41: // lhzu
|
||||||
zeroA = false;
|
zeroA = false;
|
||||||
update = true;
|
update = true;
|
||||||
case 40: // lhz
|
case 40: // lhz
|
||||||
|
fastmem = true;
|
||||||
accessSize = 16;
|
accessSize = 16;
|
||||||
break;
|
break;
|
||||||
case 43: // lhau
|
case 43: // lhau
|
||||||
@ -351,7 +404,7 @@ void JitArm::lXX(UGeckoInstruction inst)
|
|||||||
CMP(rA, EXCEPTION_DSI);
|
CMP(rA, EXCEPTION_DSI);
|
||||||
FixupBranch DoNotLoad = B_CC(CC_EQ);
|
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)
|
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
|
// Some games use this heavily in video codecs
|
||||||
// We make the assumption that this pulls from main RAM at /all/ times
|
// We make the assumption that this pulls from main RAM at /all/ times
|
||||||
void JitArm::lmw(UGeckoInstruction inst)
|
void JitArm::lmw(UGeckoInstruction inst)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user